blob: 7cef210aeb52f40152d01694ef8b26fde34cc1bc [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/v8.h"
Steve Blocka7e24c12009-10-30 11:49:00 +00006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "src/api.h"
8#include "src/ast.h"
9#include "src/bailout-reason.h"
10#include "src/base/platform/platform.h"
11#include "src/bootstrapper.h"
12#include "src/char-predicates-inl.h"
13#include "src/codegen.h"
14#include "src/compiler.h"
15#include "src/messages.h"
16#include "src/parser.h"
17#include "src/preparser.h"
18#include "src/runtime.h"
19#include "src/scanner-character-streams.h"
20#include "src/scopeinfo.h"
21#include "src/string-stream.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000022
23namespace v8 {
24namespace internal {
25
Ben Murdochb8a8cc12014-11-26 15:28:44 +000026RegExpBuilder::RegExpBuilder(Zone* zone)
27 : zone_(zone),
Ben Murdoch8b112d22011-06-08 16:22:53 +010028 pending_empty_(false),
29 characters_(NULL),
30 terms_(),
31 alternatives_()
Steve Blocka7e24c12009-10-30 11:49:00 +000032#ifdef DEBUG
Ben Murdoch8b112d22011-06-08 16:22:53 +010033 , last_added_(ADD_NONE)
Steve Blocka7e24c12009-10-30 11:49:00 +000034#endif
35 {}
36
37
38void RegExpBuilder::FlushCharacters() {
39 pending_empty_ = false;
40 if (characters_ != NULL) {
Ben Murdoch8b112d22011-06-08 16:22:53 +010041 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
Steve Blocka7e24c12009-10-30 11:49:00 +000042 characters_ = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043 text_.Add(atom, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000044 LAST(ADD_ATOM);
45 }
46}
47
48
49void RegExpBuilder::FlushText() {
50 FlushCharacters();
51 int num_text = text_.length();
52 if (num_text == 0) {
53 return;
54 } else if (num_text == 1) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000055 terms_.Add(text_.last(), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000056 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000057 RegExpText* text = new(zone()) RegExpText(zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000058 for (int i = 0; i < num_text; i++)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059 text_.Get(i)->AppendToText(text, zone());
60 terms_.Add(text, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000061 }
62 text_.Clear();
63}
64
65
66void RegExpBuilder::AddCharacter(uc16 c) {
67 pending_empty_ = false;
68 if (characters_ == NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 characters_ = new(zone()) ZoneList<uc16>(4, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000070 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071 characters_->Add(c, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000072 LAST(ADD_CHAR);
73}
74
75
76void RegExpBuilder::AddEmpty() {
77 pending_empty_ = true;
78}
79
80
81void RegExpBuilder::AddAtom(RegExpTree* term) {
82 if (term->IsEmpty()) {
83 AddEmpty();
84 return;
85 }
86 if (term->IsTextElement()) {
87 FlushCharacters();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000088 text_.Add(term, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000089 } else {
90 FlushText();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 terms_.Add(term, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000092 }
93 LAST(ADD_ATOM);
94}
95
96
97void RegExpBuilder::AddAssertion(RegExpTree* assert) {
98 FlushText();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000099 terms_.Add(assert, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000100 LAST(ADD_ASSERT);
101}
102
103
104void RegExpBuilder::NewAlternative() {
105 FlushTerms();
106}
107
108
109void RegExpBuilder::FlushTerms() {
110 FlushText();
111 int num_terms = terms_.length();
112 RegExpTree* alternative;
113 if (num_terms == 0) {
114 alternative = RegExpEmpty::GetInstance();
115 } else if (num_terms == 1) {
116 alternative = terms_.last();
117 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000118 alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000119 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120 alternatives_.Add(alternative, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000121 terms_.Clear();
122 LAST(ADD_NONE);
123}
124
125
126RegExpTree* RegExpBuilder::ToRegExp() {
127 FlushTerms();
128 int num_alternatives = alternatives_.length();
129 if (num_alternatives == 0) {
130 return RegExpEmpty::GetInstance();
131 }
132 if (num_alternatives == 1) {
133 return alternatives_.last();
134 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135 return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000136}
137
138
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000139void RegExpBuilder::AddQuantifierToAtom(
140 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000141 if (pending_empty_) {
142 pending_empty_ = false;
143 return;
144 }
145 RegExpTree* atom;
146 if (characters_ != NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147 DCHECK(last_added_ == ADD_CHAR);
Steve Blocka7e24c12009-10-30 11:49:00 +0000148 // Last atom was character.
149 Vector<const uc16> char_vector = characters_->ToConstVector();
150 int num_chars = char_vector.length();
151 if (num_chars > 1) {
152 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000153 text_.Add(new(zone()) RegExpAtom(prefix), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000154 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
155 }
156 characters_ = NULL;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100157 atom = new(zone()) RegExpAtom(char_vector);
Steve Blocka7e24c12009-10-30 11:49:00 +0000158 FlushText();
159 } else if (text_.length() > 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000160 DCHECK(last_added_ == ADD_ATOM);
Steve Blocka7e24c12009-10-30 11:49:00 +0000161 atom = text_.RemoveLast();
162 FlushText();
163 } else if (terms_.length() > 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000164 DCHECK(last_added_ == ADD_ATOM);
Steve Blocka7e24c12009-10-30 11:49:00 +0000165 atom = terms_.RemoveLast();
166 if (atom->max_match() == 0) {
167 // Guaranteed to only match an empty string.
168 LAST(ADD_TERM);
169 if (min == 0) {
170 return;
171 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172 terms_.Add(atom, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000173 return;
174 }
175 } else {
176 // Only call immediately after adding an atom or character!
177 UNREACHABLE();
178 return;
179 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180 terms_.Add(
181 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000182 LAST(ADD_TERM);
183}
184
185
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000186FunctionEntry ParseData::GetFunctionEntry(int start) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100187 // The current pre-data entry must be a FunctionEntry with the given
188 // start position.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000189 if ((function_index_ + FunctionEntry::kSize <= Length()) &&
190 (static_cast<int>(Data()[function_index_]) == start)) {
Iain Merrick9ac36c92010-09-13 15:29:50 +0100191 int index = function_index_;
192 function_index_ += FunctionEntry::kSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000193 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
194 return FunctionEntry(subvector);
Steve Blocka7e24c12009-10-30 11:49:00 +0000195 }
196 return FunctionEntry();
197}
198
199
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000200int ParseData::FunctionCount() {
201 int functions_size = FunctionsSize();
202 if (functions_size < 0) return 0;
203 if (functions_size % FunctionEntry::kSize != 0) return 0;
204 return functions_size / FunctionEntry::kSize;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100205}
206
207
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208bool ParseData::IsSane() {
Iain Merrick9ac36c92010-09-13 15:29:50 +0100209 // Check that the header data is valid and doesn't specify
210 // point to positions outside the store.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000211 int data_length = Length();
212 if (data_length < PreparseDataConstants::kHeaderSize) return false;
213 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
214 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
215 if (HasError()) return false;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100216 // Check that the space allocated for function entries is sane.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000217 int functions_size = FunctionsSize();
Iain Merrick9ac36c92010-09-13 15:29:50 +0100218 if (functions_size < 0) return false;
219 if (functions_size % FunctionEntry::kSize != 0) return false;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100220 // Check that the total size has room for header and function entries.
Iain Merrick9ac36c92010-09-13 15:29:50 +0100221 int minimum_size =
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800222 PreparseDataConstants::kHeaderSize + functions_size;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000223 if (data_length < minimum_size) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000224 return true;
225}
226
227
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000228void ParseData::Initialize() {
229 // Prepares state for use.
230 int data_length = Length();
231 if (data_length >= PreparseDataConstants::kHeaderSize) {
232 function_index_ = PreparseDataConstants::kHeaderSize;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100233 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000234}
235
236
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000237bool ParseData::HasError() {
238 return Data()[PreparseDataConstants::kHasErrorOffset];
Steve Blocka7e24c12009-10-30 11:49:00 +0000239}
240
241
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000242unsigned ParseData::Magic() {
243 return Data()[PreparseDataConstants::kMagicOffset];
244}
245
246
247unsigned ParseData::Version() {
248 return Data()[PreparseDataConstants::kVersionOffset];
249}
250
251
252int ParseData::FunctionsSize() {
253 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
254}
255
256
257void Parser::SetCachedData() {
258 if (compile_options() == ScriptCompiler::kNoCompileOptions) {
259 cached_parse_data_ = NULL;
260 } else {
261 DCHECK(info_->cached_data() != NULL);
262 if (compile_options() == ScriptCompiler::kConsumeParserCache) {
263 cached_parse_data_ = new ParseData(*info_->cached_data());
264 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000265 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000266}
267
268
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000269Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
270 DCHECK(ast_value_factory());
271 Scope* result =
272 new (zone()) Scope(parent, scope_type, ast_value_factory(), zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100273 result->Initialize();
Steve Blocka7e24c12009-10-30 11:49:00 +0000274 return result;
275}
276
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000277
Steve Blocka7e24c12009-10-30 11:49:00 +0000278// ----------------------------------------------------------------------------
279// Target is a support class to facilitate manipulation of the
280// Parser's target_stack_ (the stack of potential 'break' and
281// 'continue' statement targets). Upon construction, a new target is
282// added; it is removed upon destruction.
283
284class Target BASE_EMBEDDED {
285 public:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800286 Target(Target** variable, AstNode* node)
287 : variable_(variable), node_(node), previous_(*variable) {
288 *variable = this;
Steve Blocka7e24c12009-10-30 11:49:00 +0000289 }
290
291 ~Target() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800292 *variable_ = previous_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000293 }
294
295 Target* previous() { return previous_; }
296 AstNode* node() { return node_; }
297
298 private:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800299 Target** variable_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000300 AstNode* node_;
301 Target* previous_;
302};
303
304
305class TargetScope BASE_EMBEDDED {
306 public:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800307 explicit TargetScope(Target** variable)
308 : variable_(variable), previous_(*variable) {
309 *variable = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000310 }
311
312 ~TargetScope() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800313 *variable_ = previous_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000314 }
315
316 private:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800317 Target** variable_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000318 Target* previous_;
319};
320
321
322// ----------------------------------------------------------------------------
Steve Blocka7e24c12009-10-30 11:49:00 +0000323// The CHECK_OK macro is a convenient macro to enforce error
324// handling for functions that may fail (by returning !*ok).
325//
326// CAUTION: This macro appends extra statements after a call,
327// thus it must never be used where only a single statement
328// is correct (e.g. an if statement branch w/o braces)!
329
330#define CHECK_OK ok); \
331 if (!*ok) return NULL; \
332 ((void)0
333#define DUMMY ) // to make indentation work
334#undef DUMMY
335
336#define CHECK_FAILED /**/); \
337 if (failed_) return NULL; \
338 ((void)0
339#define DUMMY ) // to make indentation work
340#undef DUMMY
341
342// ----------------------------------------------------------------------------
343// Implementation of Parser
344
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000345class ParserTraits::Checkpoint
346 : public ParserBase<ParserTraits>::CheckpointBase {
347 public:
348 explicit Checkpoint(ParserBase<ParserTraits>* parser)
349 : CheckpointBase(parser), parser_(parser) {
350 saved_ast_node_id_gen_ = *parser_->ast_node_id_gen_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100351 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000352
353 void Restore() {
354 CheckpointBase::Restore();
355 *parser_->ast_node_id_gen_ = saved_ast_node_id_gen_;
356 }
357
358 private:
359 ParserBase<ParserTraits>* parser_;
360 AstNode::IdGen saved_ast_node_id_gen_;
361};
362
363
364bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
365 return identifier == parser_->ast_value_factory()->eval_string() ||
366 identifier == parser_->ast_value_factory()->arguments_string();
367}
368
369
370bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
371 return identifier == parser_->ast_value_factory()->prototype_string();
372}
373
374
375bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
376 return identifier == parser_->ast_value_factory()->constructor_string();
377}
378
379
380bool ParserTraits::IsThisProperty(Expression* expression) {
381 DCHECK(expression != NULL);
382 Property* property = expression->AsProperty();
383 return property != NULL &&
384 property->obj()->AsVariableProxy() != NULL &&
385 property->obj()->AsVariableProxy()->is_this();
386}
387
388
389bool ParserTraits::IsIdentifier(Expression* expression) {
390 VariableProxy* operand = expression->AsVariableProxy();
391 return operand != NULL && !operand->is_this();
392}
393
394
395void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
396 Expression* expression) {
397 if (expression->IsPropertyName()) {
398 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
399 } else {
400 fni->PushLiteralName(
401 parser_->ast_value_factory()->anonymous_function_string());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100402 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000403}
404
405
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000406void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
407 Expression* right) {
408 DCHECK(left != NULL);
409 if (left->AsProperty() != NULL &&
410 right->AsFunctionLiteral() != NULL) {
411 right->AsFunctionLiteral()->set_pretenure();
412 }
413}
Steve Blocka7e24c12009-10-30 11:49:00 +0000414
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000415
416void ParserTraits::CheckPossibleEvalCall(Expression* expression,
417 Scope* scope) {
418 VariableProxy* callee = expression->AsVariableProxy();
419 if (callee != NULL &&
420 callee->raw_name() == parser_->ast_value_factory()->eval_string()) {
421 scope->DeclarationScope()->RecordEvalCall();
422 }
423}
424
425
426Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
427 VariableProxy* proxy =
428 expression != NULL ? expression->AsVariableProxy() : NULL;
429 if (proxy != NULL) proxy->set_is_assigned();
430 return expression;
431}
432
433
434bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
435 Expression** x, Expression* y, Token::Value op, int pos,
436 AstNodeFactory<AstConstructionVisitor>* factory) {
437 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
438 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
439 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
440 double y_val = y->AsLiteral()->raw_value()->AsNumber();
441 switch (op) {
442 case Token::ADD:
443 *x = factory->NewNumberLiteral(x_val + y_val, pos);
444 return true;
445 case Token::SUB:
446 *x = factory->NewNumberLiteral(x_val - y_val, pos);
447 return true;
448 case Token::MUL:
449 *x = factory->NewNumberLiteral(x_val * y_val, pos);
450 return true;
451 case Token::DIV:
452 *x = factory->NewNumberLiteral(x_val / y_val, pos);
453 return true;
454 case Token::BIT_OR: {
455 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
456 *x = factory->NewNumberLiteral(value, pos);
457 return true;
458 }
459 case Token::BIT_AND: {
460 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
461 *x = factory->NewNumberLiteral(value, pos);
462 return true;
463 }
464 case Token::BIT_XOR: {
465 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
466 *x = factory->NewNumberLiteral(value, pos);
467 return true;
468 }
469 case Token::SHL: {
470 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
471 *x = factory->NewNumberLiteral(value, pos);
472 return true;
473 }
474 case Token::SHR: {
475 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
476 uint32_t value = DoubleToUint32(x_val) >> shift;
477 *x = factory->NewNumberLiteral(value, pos);
478 return true;
479 }
480 case Token::SAR: {
481 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
482 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
483 *x = factory->NewNumberLiteral(value, pos);
484 return true;
485 }
486 default:
487 break;
488 }
489 }
490 return false;
491}
492
493
494Expression* ParserTraits::BuildUnaryExpression(
495 Expression* expression, Token::Value op, int pos,
496 AstNodeFactory<AstConstructionVisitor>* factory) {
497 DCHECK(expression != NULL);
498 if (expression->IsLiteral()) {
499 const AstValue* literal = expression->AsLiteral()->raw_value();
500 if (op == Token::NOT) {
501 // Convert the literal to a boolean condition and negate it.
502 bool condition = literal->BooleanValue();
503 return factory->NewBooleanLiteral(!condition, pos);
504 } else if (literal->IsNumber()) {
505 // Compute some expressions involving only number literals.
506 double value = literal->AsNumber();
507 switch (op) {
508 case Token::ADD:
509 return expression;
510 case Token::SUB:
511 return factory->NewNumberLiteral(-value, pos);
512 case Token::BIT_NOT:
513 return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
514 default:
515 break;
516 }
517 }
518 }
519 // Desugar '+foo' => 'foo*1'
520 if (op == Token::ADD) {
521 return factory->NewBinaryOperation(
522 Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos);
523 }
524 // The same idea for '-foo' => 'foo*(-1)'.
525 if (op == Token::SUB) {
526 return factory->NewBinaryOperation(
527 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
528 }
529 // ...and one more time for '~foo' => 'foo^(~0)'.
530 if (op == Token::BIT_NOT) {
531 return factory->NewBinaryOperation(
532 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
533 }
534 return factory->NewUnaryOperation(op, expression, pos);
535}
536
537
538Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
539 return NewThrowError(
540 parser_->ast_value_factory()->make_reference_error_string(), message,
541 NULL, pos);
542}
543
544
545Expression* ParserTraits::NewThrowSyntaxError(
546 const char* message, const AstRawString* arg, int pos) {
547 return NewThrowError(parser_->ast_value_factory()->make_syntax_error_string(),
548 message, arg, pos);
549}
550
551
552Expression* ParserTraits::NewThrowTypeError(
553 const char* message, const AstRawString* arg, int pos) {
554 return NewThrowError(parser_->ast_value_factory()->make_type_error_string(),
555 message, arg, pos);
556}
557
558
559Expression* ParserTraits::NewThrowError(
560 const AstRawString* constructor, const char* message,
561 const AstRawString* arg, int pos) {
562 Zone* zone = parser_->zone();
563 int argc = arg != NULL ? 1 : 0;
564 const AstRawString* type =
565 parser_->ast_value_factory()->GetOneByteString(message);
566 ZoneList<const AstRawString*>* array =
567 new (zone) ZoneList<const AstRawString*>(argc, zone);
568 if (arg != NULL) {
569 array->Add(arg, zone);
570 }
571 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
572 args->Add(parser_->factory()->NewStringLiteral(type, pos), zone);
573 args->Add(parser_->factory()->NewStringListLiteral(array, pos), zone);
574 CallRuntime* call_constructor =
575 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
576 return parser_->factory()->NewThrow(call_constructor, pos);
577}
578
579
580void ParserTraits::ReportMessageAt(Scanner::Location source_location,
581 const char* message,
582 const char* arg,
583 bool is_reference_error) {
584 if (parser_->stack_overflow()) {
585 // Suppress the error message (syntax error or such) in the presence of a
586 // stack overflow. The isolate allows only one pending exception at at time
587 // and we want to report the stack overflow later.
588 return;
589 }
590 parser_->has_pending_error_ = true;
591 parser_->pending_error_location_ = source_location;
592 parser_->pending_error_message_ = message;
593 parser_->pending_error_char_arg_ = arg;
594 parser_->pending_error_arg_ = NULL;
595 parser_->pending_error_is_reference_error_ = is_reference_error;
596}
597
598
599void ParserTraits::ReportMessage(const char* message,
600 const char* arg,
601 bool is_reference_error) {
602 Scanner::Location source_location = parser_->scanner()->location();
603 ReportMessageAt(source_location, message, arg, is_reference_error);
604}
605
606
607void ParserTraits::ReportMessage(const char* message,
608 const AstRawString* arg,
609 bool is_reference_error) {
610 Scanner::Location source_location = parser_->scanner()->location();
611 ReportMessageAt(source_location, message, arg, is_reference_error);
612}
613
614
615void ParserTraits::ReportMessageAt(Scanner::Location source_location,
616 const char* message,
617 const AstRawString* arg,
618 bool is_reference_error) {
619 if (parser_->stack_overflow()) {
620 // Suppress the error message (syntax error or such) in the presence of a
621 // stack overflow. The isolate allows only one pending exception at at time
622 // and we want to report the stack overflow later.
623 return;
624 }
625 parser_->has_pending_error_ = true;
626 parser_->pending_error_location_ = source_location;
627 parser_->pending_error_message_ = message;
628 parser_->pending_error_char_arg_ = NULL;
629 parser_->pending_error_arg_ = arg;
630 parser_->pending_error_is_reference_error_ = is_reference_error;
631}
632
633
634const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
635 const AstRawString* result =
636 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
637 DCHECK(result != NULL);
638 return result;
639}
640
641
642const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) {
643 double double_value = parser_->scanner()->DoubleValue();
644 char array[100];
645 const char* string =
646 DoubleToCString(double_value, Vector<char>(array, arraysize(array)));
647 return ast_value_factory()->GetOneByteString(string);
648}
649
650
651const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
652 return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
653}
654
655
656Expression* ParserTraits::ThisExpression(
657 Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) {
658 return factory->NewVariableProxy(scope->receiver(), pos);
659}
660
661Expression* ParserTraits::SuperReference(
662 Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) {
663 return factory->NewSuperReference(
664 ThisExpression(scope, factory, pos)->AsVariableProxy(),
665 pos);
666}
667
668Expression* ParserTraits::ClassLiteral(
669 const AstRawString* name, Expression* extends, Expression* constructor,
670 ZoneList<ObjectLiteral::Property*>* properties, int pos,
671 AstNodeFactory<AstConstructionVisitor>* factory) {
672 return factory->NewClassLiteral(name, extends, constructor, properties, pos);
673}
674
675Literal* ParserTraits::ExpressionFromLiteral(
676 Token::Value token, int pos,
677 Scanner* scanner,
678 AstNodeFactory<AstConstructionVisitor>* factory) {
679 switch (token) {
680 case Token::NULL_LITERAL:
681 return factory->NewNullLiteral(pos);
682 case Token::TRUE_LITERAL:
683 return factory->NewBooleanLiteral(true, pos);
684 case Token::FALSE_LITERAL:
685 return factory->NewBooleanLiteral(false, pos);
686 case Token::NUMBER: {
687 double value = scanner->DoubleValue();
688 return factory->NewNumberLiteral(value, pos);
689 }
690 default:
691 DCHECK(false);
692 }
693 return NULL;
694}
695
696
697Expression* ParserTraits::ExpressionFromIdentifier(
698 const AstRawString* name, int pos, Scope* scope,
699 AstNodeFactory<AstConstructionVisitor>* factory) {
700 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
701 // The name may refer to a module instance object, so its type is unknown.
702#ifdef DEBUG
703 if (FLAG_print_interface_details)
704 PrintF("# Variable %.*s ", name->length(), name->raw_data());
705#endif
706 Interface* interface = Interface::NewUnknown(parser_->zone());
707 return scope->NewUnresolved(factory, name, interface, pos);
708}
709
710
711Expression* ParserTraits::ExpressionFromString(
712 int pos, Scanner* scanner,
713 AstNodeFactory<AstConstructionVisitor>* factory) {
714 const AstRawString* symbol = GetSymbol(scanner);
715 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
716 return factory->NewStringLiteral(symbol, pos);
717}
718
719
720Expression* ParserTraits::GetIterator(
721 Expression* iterable, AstNodeFactory<AstConstructionVisitor>* factory) {
722 Expression* iterator_symbol_literal =
723 factory->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition);
724 int pos = iterable->position();
725 Expression* prop =
726 factory->NewProperty(iterable, iterator_symbol_literal, pos);
727 Zone* zone = parser_->zone();
728 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
729 return factory->NewCall(prop, args, pos);
730}
731
732
733Literal* ParserTraits::GetLiteralTheHole(
734 int position, AstNodeFactory<AstConstructionVisitor>* factory) {
735 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
736}
737
738
739Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
740 return parser_->ParseV8Intrinsic(ok);
741}
742
743
744FunctionLiteral* ParserTraits::ParseFunctionLiteral(
745 const AstRawString* name, Scanner::Location function_name_location,
746 bool name_is_strict_reserved, FunctionKind kind,
747 int function_token_position, FunctionLiteral::FunctionType type,
748 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
749 return parser_->ParseFunctionLiteral(
750 name, function_name_location, name_is_strict_reserved, kind,
751 function_token_position, type, arity_restriction, ok);
752}
753
754
755Parser::Parser(CompilationInfo* info, ParseInfo* parse_info)
756 : ParserBase<ParserTraits>(&scanner_, parse_info->stack_limit,
757 info->extension(), NULL, info->zone(),
758 info->ast_node_id_gen(), this),
759 scanner_(parse_info->unicode_cache),
760 reusable_preparser_(NULL),
761 original_scope_(NULL),
762 target_stack_(NULL),
763 cached_parse_data_(NULL),
764 info_(info),
765 has_pending_error_(false),
766 pending_error_message_(NULL),
767 pending_error_arg_(NULL),
768 pending_error_char_arg_(NULL),
769 total_preparse_skipped_(0),
770 pre_parse_timer_(NULL) {
771 DCHECK(!script().is_null() || info->source_stream() != NULL);
772 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
773 set_allow_modules(!info->is_native() && FLAG_harmony_modules);
774 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
775 set_allow_lazy(false); // Must be explicitly enabled.
776 set_allow_arrow_functions(FLAG_harmony_arrow_functions);
777 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
778 set_allow_classes(FLAG_harmony_classes);
779 set_allow_harmony_object_literals(FLAG_harmony_object_literals);
780 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
781 ++feature) {
782 use_counts_[feature] = 0;
783 }
784 if (info->ast_value_factory() == NULL) {
785 // info takes ownership of AstValueFactory.
786 info->SetAstValueFactory(
787 new AstValueFactory(zone(), parse_info->hash_seed));
788 }
789}
790
791
792FunctionLiteral* Parser::ParseProgram() {
793 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
794 // see comment for HistogramTimerScope class.
795
796 // It's OK to use the counters here, since this function is only called in
797 // the main thread.
798 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true);
799 Handle<String> source(String::cast(script()->source()));
Steve Block44f0eee2011-05-26 01:26:41 +0100800 isolate()->counters()->total_parse_size()->Increment(source->length());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000801 base::ElapsedTimer timer;
802 if (FLAG_trace_parse) {
803 timer.Start();
804 }
805 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000806
807 // Initialize parser state.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000808 CompleteParserRecorder recorder;
809
810 if (compile_options() == ScriptCompiler::kProduceParserCache) {
811 log_ = &recorder;
812 } else if (compile_options() == ScriptCompiler::kConsumeParserCache) {
813 cached_parse_data_->Initialize();
814 }
815
816 source = String::Flatten(source);
817 FunctionLiteral* result;
818
819 Scope* top_scope = NULL;
820 Scope* eval_scope = NULL;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100821 if (source->IsExternalTwoByteString()) {
822 // Notice that the stream is destroyed at the end of the branch block.
823 // The last line of the blocks can't be moved outside, even though they're
824 // identical calls.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100825 ExternalTwoByteStringUtf16CharacterStream stream(
Ben Murdochb0fe1622011-05-05 13:52:32 +0100826 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
Steve Block9fac8402011-05-12 15:51:54 +0100827 scanner_.Initialize(&stream);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000828 result = DoParseProgram(info(), &top_scope, &eval_scope);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100829 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100830 GenericStringUtf16CharacterStream stream(source, 0, source->length());
Steve Block9fac8402011-05-12 15:51:54 +0100831 scanner_.Initialize(&stream);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000832 result = DoParseProgram(info(), &top_scope, &eval_scope);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100833 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000834 top_scope->set_end_position(source->length());
835 if (eval_scope != NULL) {
836 eval_scope->set_end_position(source->length());
Steve Blocka7e24c12009-10-30 11:49:00 +0000837 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000838 HandleSourceURLComments();
Steve Blocka7e24c12009-10-30 11:49:00 +0000839
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000840 if (FLAG_trace_parse && result != NULL) {
841 double ms = timer.Elapsed().InMillisecondsF();
842 if (info()->is_eval()) {
843 PrintF("[parsing eval");
844 } else if (info()->script()->name()->IsString()) {
845 String* name = String::cast(info()->script()->name());
846 SmartArrayPointer<char> name_chars = name->ToCString();
847 PrintF("[parsing script: %s", name_chars.get());
848 } else {
849 PrintF("[parsing script");
850 }
851 PrintF(" - took %0.3f ms]\n", ms);
852 }
853 if (compile_options() == ScriptCompiler::kProduceParserCache) {
854 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
855 log_ = NULL;
856 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000857 return result;
858}
859
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100860
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000861FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope,
862 Scope** eval_scope) {
863 DCHECK(scope_ == NULL);
864 DCHECK(target_stack_ == NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000865
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000866 FunctionLiteral* result = NULL;
867 {
868 *scope = NewScope(scope_, GLOBAL_SCOPE);
869 info->SetGlobalScope(*scope);
870 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
871 *scope = Scope::DeserializeScopeChain(*info->context(), *scope, zone());
872 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
873 // means the Parser cannot operate independent of the V8 heap. Tell the
874 // string table to internalize strings and values right after they're
875 // created.
876 ast_value_factory()->Internalize(isolate());
877 }
878 original_scope_ = *scope;
879 if (info->is_eval()) {
880 if (!(*scope)->is_global_scope() || info->strict_mode() == STRICT) {
881 *scope = NewScope(*scope, EVAL_SCOPE);
882 }
883 } else if (info->is_global()) {
884 *scope = NewScope(*scope, GLOBAL_SCOPE);
885 }
886 (*scope)->set_start_position(0);
887 // End position will be set by the caller.
888
889 // Compute the parsing mode.
890 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
891 if (allow_natives_syntax() || extension_ != NULL ||
892 (*scope)->is_eval_scope()) {
893 mode = PARSE_EAGERLY;
894 }
895 ParsingModeScope parsing_mode(this, mode);
896
897 // Enters 'scope'.
898 FunctionState function_state(&function_state_, &scope_, *scope, zone(),
899 ast_value_factory(), info->ast_node_id_gen());
900
901 scope_->SetStrictMode(info->strict_mode());
902 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
903 bool ok = true;
904 int beg_pos = scanner()->location().beg_pos;
905 ParseSourceElements(body, Token::EOS, info->is_eval(), true, eval_scope,
906 &ok);
907
908 if (ok && strict_mode() == STRICT) {
909 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
910 }
911
912 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) {
913 CheckConflictingVarDeclarations(scope_, &ok);
914 }
915
916 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
917 if (body->length() != 1 ||
918 !body->at(0)->IsExpressionStatement() ||
919 !body->at(0)->AsExpressionStatement()->
920 expression()->IsFunctionLiteral()) {
921 ReportMessage("single_function_literal");
922 ok = false;
923 }
924 }
925
926 if (ok) {
927 result = factory()->NewFunctionLiteral(
928 ast_value_factory()->empty_string(), ast_value_factory(), scope_,
929 body, function_state.materialized_literal_count(),
930 function_state.expected_property_count(),
931 function_state.handler_count(), 0,
932 FunctionLiteral::kNoDuplicateParameters,
933 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
934 FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0);
935 result->set_ast_properties(factory()->visitor()->ast_properties());
936 result->set_dont_optimize_reason(
937 factory()->visitor()->dont_optimize_reason());
938 }
939 }
940
941 // Make sure the target stack is empty.
942 DCHECK(target_stack_ == NULL);
943
944 return result;
945}
946
947
948FunctionLiteral* Parser::ParseLazy() {
949 // It's OK to use the counters here, since this function is only called in
950 // the main thread.
951 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy());
952 Handle<String> source(String::cast(script()->source()));
953 isolate()->counters()->total_parse_size()->Increment(source->length());
954 base::ElapsedTimer timer;
955 if (FLAG_trace_parse) {
956 timer.Start();
957 }
958 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
959
Ben Murdochb0fe1622011-05-05 13:52:32 +0100960 // Initialize parser state.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000961 source = String::Flatten(source);
962 FunctionLiteral* result;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100963 if (source->IsExternalTwoByteString()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100964 ExternalTwoByteStringUtf16CharacterStream stream(
Ben Murdochb0fe1622011-05-05 13:52:32 +0100965 Handle<ExternalTwoByteString>::cast(source),
Steve Block44f0eee2011-05-26 01:26:41 +0100966 shared_info->start_position(),
967 shared_info->end_position());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000968 result = ParseLazy(&stream);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100969 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100970 GenericStringUtf16CharacterStream stream(source,
971 shared_info->start_position(),
972 shared_info->end_position());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000973 result = ParseLazy(&stream);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100974 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000975
976 if (FLAG_trace_parse && result != NULL) {
977 double ms = timer.Elapsed().InMillisecondsF();
978 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
979 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
980 }
981 return result;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100982}
983
984
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000985FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
986 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
Steve Block9fac8402011-05-12 15:51:54 +0100987 scanner_.Initialize(source);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000988 DCHECK(scope_ == NULL);
989 DCHECK(target_stack_ == NULL);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100990
Steve Block44f0eee2011-05-26 01:26:41 +0100991 Handle<String> name(String::cast(shared_info->name()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000992 DCHECK(ast_value_factory());
993 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
994 const AstRawString* raw_name = ast_value_factory()->GetString(name);
995 fni_->PushEnclosingName(raw_name);
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100996
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000997 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
Steve Blocka7e24c12009-10-30 11:49:00 +0000998
999 // Place holder for the result.
1000 FunctionLiteral* result = NULL;
1001
1002 {
1003 // Parse the function literal.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001004 Scope* scope = NewScope(scope_, GLOBAL_SCOPE);
1005 info()->SetGlobalScope(scope);
1006 if (!info()->closure().is_null()) {
1007 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
1008 zone());
Steve Block44f0eee2011-05-26 01:26:41 +01001009 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001010 original_scope_ = scope;
1011 FunctionState function_state(&function_state_, &scope_, scope, zone(),
1012 ast_value_factory(),
1013 info()->ast_node_id_gen());
1014 DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
1015 DCHECK(info()->strict_mode() == shared_info->strict_mode());
1016 scope->SetStrictMode(shared_info->strict_mode());
1017 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001018 ? (shared_info->is_anonymous()
1019 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1020 : FunctionLiteral::NAMED_EXPRESSION)
1021 : FunctionLiteral::DECLARATION;
Steve Blocka7e24c12009-10-30 11:49:00 +00001022 bool ok = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001023
1024 if (shared_info->is_arrow()) {
1025 Expression* expression = ParseExpression(false, &ok);
1026 DCHECK(expression->IsFunctionLiteral());
1027 result = expression->AsFunctionLiteral();
1028 } else {
1029 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
1030 false, // Strict mode name already checked.
1031 shared_info->kind(), RelocInfo::kNoPosition,
1032 function_type,
1033 FunctionLiteral::NORMAL_ARITY, &ok);
1034 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001035 // Make sure the results agree.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001036 DCHECK(ok == (result != NULL));
Steve Blocka7e24c12009-10-30 11:49:00 +00001037 }
1038
1039 // Make sure the target stack is empty.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001040 DCHECK(target_stack_ == NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00001041
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001042 if (result != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +01001043 Handle<String> inferred_name(shared_info->inferred_name());
Ben Murdochb0fe1622011-05-05 13:52:32 +01001044 result->set_inferred_name(inferred_name);
Steve Blocka7e24c12009-10-30 11:49:00 +00001045 }
1046 return result;
1047}
1048
Ben Murdochf87a2032010-10-22 12:50:53 +01001049
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001050void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001051 int end_token, bool is_eval, bool is_global,
1052 Scope** eval_scope, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001053 // SourceElements ::
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001054 // (ModuleElement)* <end_token>
Steve Blocka7e24c12009-10-30 11:49:00 +00001055
1056 // Allocate a target stack to use for this set of source
1057 // elements. This way, all scripts and functions get their own
1058 // target stack thus avoiding illegal breaks and continues across
1059 // functions.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001060 TargetScope scope(&this->target_stack_);
Steve Blocka7e24c12009-10-30 11:49:00 +00001061
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001062 DCHECK(processor != NULL);
Steve Block1e0659c2011-05-24 12:43:12 +01001063 bool directive_prologue = true; // Parsing directive prologue.
1064
Steve Blocka7e24c12009-10-30 11:49:00 +00001065 while (peek() != end_token) {
Steve Block1e0659c2011-05-24 12:43:12 +01001066 if (directive_prologue && peek() != Token::STRING) {
1067 directive_prologue = false;
1068 }
1069
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001070 Scanner::Location token_loc = scanner()->peek_location();
1071 Statement* stat;
1072 if (is_global && !is_eval) {
1073 stat = ParseModuleElement(NULL, CHECK_OK);
1074 } else {
1075 stat = ParseBlockElement(NULL, CHECK_OK);
1076 }
Steve Block1e0659c2011-05-24 12:43:12 +01001077 if (stat == NULL || stat->IsEmpty()) {
1078 directive_prologue = false; // End of directive prologue.
1079 continue;
1080 }
1081
1082 if (directive_prologue) {
1083 // A shot at a directive.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001084 ExpressionStatement* e_stat;
1085 Literal* literal;
Steve Block1e0659c2011-05-24 12:43:12 +01001086 // Still processing directive prologue?
1087 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1088 (literal = e_stat->expression()->AsLiteral()) != NULL &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001089 literal->raw_value()->IsString()) {
1090 // Check "use strict" directive (ES5 14.1) and "use asm" directive. Only
1091 // one can be present.
1092 if (strict_mode() == SLOPPY &&
1093 literal->raw_value()->AsString() ==
1094 ast_value_factory()->use_strict_string() &&
Steve Block1e0659c2011-05-24 12:43:12 +01001095 token_loc.end_pos - token_loc.beg_pos ==
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001096 ast_value_factory()->use_strict_string()->length() + 2) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001097 // TODO(mstarzinger): Global strict eval calls, need their own scope
1098 // as specified in ES5 10.4.2(3). The correct fix would be to always
1099 // add this scope in DoParseProgram(), but that requires adaptations
1100 // all over the code base, so we go with a quick-fix for now.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001101 // In the same manner, we have to patch the parsing mode.
1102 if (is_eval && !scope_->is_eval_scope()) {
1103 DCHECK(scope_->is_global_scope());
1104 Scope* scope = NewScope(scope_, EVAL_SCOPE);
1105 scope->set_start_position(scope_->start_position());
1106 scope->set_end_position(scope_->end_position());
1107 scope_ = scope;
1108 if (eval_scope != NULL) {
1109 // Caller will correct the positions of the ad hoc eval scope.
1110 *eval_scope = scope;
1111 }
1112 mode_ = PARSE_EAGERLY;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001113 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001114 scope_->SetStrictMode(STRICT);
Steve Block1e0659c2011-05-24 12:43:12 +01001115 // "use strict" is the only directive for now.
1116 directive_prologue = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001117 } else if (literal->raw_value()->AsString() ==
1118 ast_value_factory()->use_asm_string() &&
1119 token_loc.end_pos - token_loc.beg_pos ==
1120 ast_value_factory()->use_asm_string()->length() + 2) {
1121 // Store the usage count; The actual use counter on the isolate is
1122 // incremented after parsing is done.
1123 ++use_counts_[v8::Isolate::kUseAsm];
1124 scope_->SetAsmModule();
Steve Block1e0659c2011-05-24 12:43:12 +01001125 }
1126 } else {
1127 // End of the directive prologue.
1128 directive_prologue = false;
1129 }
1130 }
1131
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001132 processor->Add(stat, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00001133 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001134
Steve Blocka7e24c12009-10-30 11:49:00 +00001135 return 0;
1136}
1137
1138
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001139Statement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001140 bool* ok) {
1141 // (Ecma 262 5th Edition, clause 14):
1142 // SourceElement:
1143 // Statement
1144 // FunctionDeclaration
1145 //
1146 // In harmony mode we allow additionally the following productions
1147 // ModuleElement:
1148 // LetDeclaration
1149 // ConstDeclaration
1150 // ModuleDeclaration
1151 // ImportDeclaration
1152 // ExportDeclaration
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001153 // GeneratorDeclaration
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001154
1155 switch (peek()) {
1156 case Token::FUNCTION:
1157 return ParseFunctionDeclaration(NULL, ok);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001158 case Token::CLASS:
1159 return ParseClassDeclaration(NULL, ok);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001160 case Token::IMPORT:
1161 return ParseImportDeclaration(ok);
1162 case Token::EXPORT:
1163 return ParseExportDeclaration(ok);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001164 case Token::CONST:
1165 return ParseVariableStatement(kModuleElement, NULL, ok);
1166 case Token::LET:
1167 DCHECK(allow_harmony_scoping());
1168 if (strict_mode() == STRICT) {
1169 return ParseVariableStatement(kModuleElement, NULL, ok);
1170 }
1171 // Fall through.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001172 default: {
1173 Statement* stmt = ParseStatement(labels, CHECK_OK);
1174 // Handle 'module' as a context-sensitive keyword.
1175 if (FLAG_harmony_modules &&
1176 peek() == Token::IDENTIFIER &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001177 !scanner()->HasAnyLineTerminatorBeforeNext() &&
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001178 stmt != NULL) {
1179 ExpressionStatement* estmt = stmt->AsExpressionStatement();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001180 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL &&
1181 estmt->expression()->AsVariableProxy()->raw_name() ==
1182 ast_value_factory()->module_string() &&
1183 !scanner()->literal_contains_escapes()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001184 return ParseModuleDeclaration(NULL, ok);
1185 }
1186 }
1187 return stmt;
1188 }
1189 }
1190}
1191
1192
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001193Statement* Parser::ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
1194 bool* ok) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001195 // ModuleDeclaration:
1196 // 'module' Identifier Module
1197
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001198 int pos = peek_position();
1199 const AstRawString* name =
1200 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001201
1202#ifdef DEBUG
1203 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001204 PrintF("# Module %.*s ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001205#endif
1206
1207 Module* module = ParseModule(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001208 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001209 Declaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001210 factory()->NewModuleDeclaration(proxy, module, scope_, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001211 Declare(declaration, true, CHECK_OK);
1212
1213#ifdef DEBUG
1214 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001215 PrintF("# Module %.*s ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001216 if (FLAG_print_interfaces) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001217 PrintF("module %.*s: ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001218 module->interface()->Print();
1219 }
1220#endif
1221
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001222 if (names) names->Add(name, zone());
1223 if (module->body() == NULL)
1224 return factory()->NewEmptyStatement(pos);
1225 else
1226 return factory()->NewModuleStatement(proxy, module->body(), pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001227}
1228
1229
1230Module* Parser::ParseModule(bool* ok) {
1231 // Module:
1232 // '{' ModuleElement '}'
1233 // '=' ModulePath ';'
1234 // 'at' String ';'
1235
1236 switch (peek()) {
1237 case Token::LBRACE:
1238 return ParseModuleLiteral(ok);
1239
1240 case Token::ASSIGN: {
1241 Expect(Token::ASSIGN, CHECK_OK);
1242 Module* result = ParseModulePath(CHECK_OK);
1243 ExpectSemicolon(CHECK_OK);
1244 return result;
1245 }
1246
1247 default: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001248 ExpectContextualKeyword(CStrVector("at"), CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001249 Module* result = ParseModuleUrl(CHECK_OK);
1250 ExpectSemicolon(CHECK_OK);
1251 return result;
1252 }
1253 }
1254}
1255
1256
1257Module* Parser::ParseModuleLiteral(bool* ok) {
1258 // Module:
1259 // '{' ModuleElement '}'
1260
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001261 int pos = peek_position();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001262 // Construct block expecting 16 statements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001263 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001264#ifdef DEBUG
1265 if (FLAG_print_interface_details) PrintF("# Literal ");
1266#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001267 Scope* scope = NewScope(scope_, MODULE_SCOPE);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001268
1269 Expect(Token::LBRACE, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001270 scope->set_start_position(scanner()->location().beg_pos);
1271 scope->SetStrictMode(STRICT);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001272
1273 {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001274 BlockState block_state(&scope_, scope);
1275 TargetCollector collector(zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001276 Target target(&this->target_stack_, &collector);
1277 Target target_body(&this->target_stack_, body);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001278
1279 while (peek() != Token::RBRACE) {
1280 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1281 if (stat && !stat->IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001282 body->AddStatement(stat, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001283 }
1284 }
1285 }
1286
1287 Expect(Token::RBRACE, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001288 scope->set_end_position(scanner()->location().end_pos);
1289 body->set_scope(scope);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001290
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001291 // Check that all exports are bound.
1292 Interface* interface = scope->interface();
1293 for (Interface::Iterator it = interface->iterator();
1294 !it.done(); it.Advance()) {
1295 if (scope->LookupLocal(it.name()) == NULL) {
1296 ParserTraits::ReportMessage("module_export_undefined", it.name());
1297 *ok = false;
1298 return NULL;
1299 }
1300 }
1301
1302 interface->MakeModule(ok);
1303 DCHECK(*ok);
1304 interface->Freeze(ok);
1305 DCHECK(*ok);
1306 return factory()->NewModuleLiteral(body, interface, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001307}
1308
1309
1310Module* Parser::ParseModulePath(bool* ok) {
1311 // ModulePath:
1312 // Identifier
1313 // ModulePath '.' Identifier
1314
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001315 int pos = peek_position();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001316 Module* result = ParseModuleVariable(CHECK_OK);
1317 while (Check(Token::PERIOD)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001318 const AstRawString* name = ParseIdentifierName(CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001319#ifdef DEBUG
1320 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001321 PrintF("# Path .%.*s ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001322#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001323 Module* member = factory()->NewModulePath(result, name, pos);
1324 result->interface()->Add(name, member->interface(), zone(), ok);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001325 if (!*ok) {
1326#ifdef DEBUG
1327 if (FLAG_print_interfaces) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001328 PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001329 PrintF("result: ");
1330 result->interface()->Print();
1331 PrintF("member: ");
1332 member->interface()->Print();
1333 }
1334#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001335 ParserTraits::ReportMessage("invalid_module_path", name);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001336 return NULL;
1337 }
1338 result = member;
1339 }
1340
1341 return result;
1342}
1343
1344
1345Module* Parser::ParseModuleVariable(bool* ok) {
1346 // ModulePath:
1347 // Identifier
1348
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001349 int pos = peek_position();
1350 const AstRawString* name =
1351 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001352#ifdef DEBUG
1353 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001354 PrintF("# Module variable %.*s ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001355#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001356 VariableProxy* proxy = scope_->NewUnresolved(
1357 factory(), name, Interface::NewModule(zone()),
1358 scanner()->location().beg_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001359
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001360 return factory()->NewModuleVariable(proxy, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001361}
1362
1363
1364Module* Parser::ParseModuleUrl(bool* ok) {
1365 // Module:
1366 // String
1367
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001368 int pos = peek_position();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001369 Expect(Token::STRING, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001370 const AstRawString* symbol = GetSymbol(scanner());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001371
1372 // TODO(ES6): Request JS resource from environment...
1373
1374#ifdef DEBUG
1375 if (FLAG_print_interface_details) PrintF("# Url ");
1376#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001377
1378 // Create an empty literal as long as the feature isn't finished.
1379 USE(symbol);
1380 Scope* scope = NewScope(scope_, MODULE_SCOPE);
1381 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
1382 body->set_scope(scope);
1383 Interface* interface = scope->interface();
1384 Module* result = factory()->NewModuleLiteral(body, interface, pos);
1385 interface->Freeze(ok);
1386 DCHECK(*ok);
1387 interface->Unify(scope->interface(), zone(), ok);
1388 DCHECK(*ok);
1389 return result;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001390}
1391
1392
1393Module* Parser::ParseModuleSpecifier(bool* ok) {
1394 // ModuleSpecifier:
1395 // String
1396 // ModulePath
1397
1398 if (peek() == Token::STRING) {
1399 return ParseModuleUrl(ok);
1400 } else {
1401 return ParseModulePath(ok);
1402 }
1403}
1404
1405
1406Block* Parser::ParseImportDeclaration(bool* ok) {
1407 // ImportDeclaration:
1408 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1409 //
1410 // TODO(ES6): implement destructuring ImportSpecifiers
1411
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001412 int pos = peek_position();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001413 Expect(Token::IMPORT, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001414 ZoneList<const AstRawString*> names(1, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001415
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001416 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1417 names.Add(name, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001418 while (peek() == Token::COMMA) {
1419 Consume(Token::COMMA);
1420 name = ParseIdentifierName(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001421 names.Add(name, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001422 }
1423
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001424 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001425 Module* module = ParseModuleSpecifier(CHECK_OK);
1426 ExpectSemicolon(CHECK_OK);
1427
1428 // Generate a separate declaration for each identifier.
1429 // TODO(ES6): once we implement destructuring, make that one declaration.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001430 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001431 for (int i = 0; i < names.length(); ++i) {
1432#ifdef DEBUG
1433 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001434 PrintF("# Import %.*s ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001435#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001436 Interface* interface = Interface::NewUnknown(zone());
1437 module->interface()->Add(names[i], interface, zone(), ok);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001438 if (!*ok) {
1439#ifdef DEBUG
1440 if (FLAG_print_interfaces) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001441 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(),
1442 name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001443 PrintF("module: ");
1444 module->interface()->Print();
1445 }
1446#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001447 ParserTraits::ReportMessage("invalid_module_path", name);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001448 return NULL;
1449 }
1450 VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1451 Declaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001452 factory()->NewImportDeclaration(proxy, module, scope_, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001453 Declare(declaration, true, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001454 }
1455
1456 return block;
1457}
1458
1459
1460Statement* Parser::ParseExportDeclaration(bool* ok) {
1461 // ExportDeclaration:
1462 // 'export' Identifier (',' Identifier)* ';'
1463 // 'export' VariableDeclaration
1464 // 'export' FunctionDeclaration
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001465 // 'export' GeneratorDeclaration
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001466 // 'export' ModuleDeclaration
1467 //
1468 // TODO(ES6): implement structuring ExportSpecifiers
1469
1470 Expect(Token::EXPORT, CHECK_OK);
1471
1472 Statement* result = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001473 ZoneList<const AstRawString*> names(1, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001474 switch (peek()) {
1475 case Token::IDENTIFIER: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001476 int pos = position();
1477 const AstRawString* name =
1478 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001479 // Handle 'module' as a context-sensitive keyword.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001480 if (name != ast_value_factory()->module_string()) {
1481 names.Add(name, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001482 while (peek() == Token::COMMA) {
1483 Consume(Token::COMMA);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001484 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1485 names.Add(name, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001486 }
1487 ExpectSemicolon(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001488 result = factory()->NewEmptyStatement(pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001489 } else {
1490 result = ParseModuleDeclaration(&names, CHECK_OK);
1491 }
1492 break;
1493 }
1494
1495 case Token::FUNCTION:
1496 result = ParseFunctionDeclaration(&names, CHECK_OK);
1497 break;
1498
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001499 case Token::CLASS:
1500 result = ParseClassDeclaration(&names, CHECK_OK);
1501 break;
1502
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001503 case Token::VAR:
1504 case Token::LET:
1505 case Token::CONST:
1506 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1507 break;
1508
1509 default:
1510 *ok = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001511 ReportUnexpectedToken(scanner()->current_token());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001512 return NULL;
1513 }
1514
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001515 // Every export of a module may be assigned.
1516 for (int i = 0; i < names.length(); ++i) {
1517 Variable* var = scope_->Lookup(names[i]);
1518 if (var == NULL) {
1519 // TODO(sigurds) This is an export that has no definition yet,
1520 // not clear what to do in this case.
1521 continue;
1522 }
1523 if (!IsImmutableVariableMode(var->mode())) {
1524 var->set_maybe_assigned();
1525 }
1526 }
1527
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001528 // Extract declared names into export declarations and interface.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001529 Interface* interface = scope_->interface();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001530 for (int i = 0; i < names.length(); ++i) {
1531#ifdef DEBUG
1532 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001533 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001534#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001535 Interface* inner = Interface::NewUnknown(zone());
1536 interface->Add(names[i], inner, zone(), CHECK_OK);
1537 if (!*ok)
1538 return NULL;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001539 VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1540 USE(proxy);
1541 // TODO(rossberg): Rethink whether we actually need to store export
1542 // declarations (for compilation?).
1543 // ExportDeclaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001544 // factory()->NewExportDeclaration(proxy, scope_, position);
1545 // scope_->AddDeclaration(declaration);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001546 }
1547
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001548 DCHECK(result != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001549 return result;
1550}
1551
1552
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001553Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001554 bool* ok) {
1555 // (Ecma 262 5th Edition, clause 14):
1556 // SourceElement:
1557 // Statement
1558 // FunctionDeclaration
1559 //
1560 // In harmony mode we allow additionally the following productions
1561 // BlockElement (aka SourceElement):
1562 // LetDeclaration
1563 // ConstDeclaration
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001564 // GeneratorDeclaration
1565 // ClassDeclaration
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001566
1567 switch (peek()) {
1568 case Token::FUNCTION:
1569 return ParseFunctionDeclaration(NULL, ok);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001570 case Token::CLASS:
1571 return ParseClassDeclaration(NULL, ok);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001572 case Token::CONST:
1573 return ParseVariableStatement(kModuleElement, NULL, ok);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001574 case Token::LET:
1575 DCHECK(allow_harmony_scoping());
1576 if (strict_mode() == STRICT) {
1577 return ParseVariableStatement(kModuleElement, NULL, ok);
1578 }
1579 // Fall through.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001580 default:
1581 return ParseStatement(labels, ok);
1582 }
1583}
1584
1585
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001586Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1587 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001588 // Statement ::
1589 // Block
1590 // VariableStatement
1591 // EmptyStatement
1592 // ExpressionStatement
1593 // IfStatement
1594 // IterationStatement
1595 // ContinueStatement
1596 // BreakStatement
1597 // ReturnStatement
1598 // WithStatement
1599 // LabelledStatement
1600 // SwitchStatement
1601 // ThrowStatement
1602 // TryStatement
1603 // DebuggerStatement
1604
1605 // Note: Since labels can only be used by 'break' and 'continue'
1606 // statements, which themselves are only valid within blocks,
1607 // iterations or 'switch' statements (i.e., BreakableStatements),
1608 // labels can be simply ignored in all other cases; except for
1609 // trivial labeled break statements 'label: break label' which is
1610 // parsed into an empty statement.
Steve Blocka7e24c12009-10-30 11:49:00 +00001611 switch (peek()) {
1612 case Token::LBRACE:
1613 return ParseBlock(labels, ok);
1614
Steve Blocka7e24c12009-10-30 11:49:00 +00001615 case Token::SEMICOLON:
1616 Next();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001617 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00001618
1619 case Token::IF:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001620 return ParseIfStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001621
1622 case Token::DO:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001623 return ParseDoWhileStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001624
1625 case Token::WHILE:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001626 return ParseWhileStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001627
1628 case Token::FOR:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001629 return ParseForStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001630
1631 case Token::CONTINUE:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001632 return ParseContinueStatement(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001633
1634 case Token::BREAK:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001635 return ParseBreakStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001636
1637 case Token::RETURN:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001638 return ParseReturnStatement(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001639
1640 case Token::WITH:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001641 return ParseWithStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001642
1643 case Token::SWITCH:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001644 return ParseSwitchStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001645
1646 case Token::THROW:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001647 return ParseThrowStatement(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001648
1649 case Token::TRY: {
1650 // NOTE: It is somewhat complicated to have labels on
1651 // try-statements. When breaking out of a try-finally statement,
1652 // one must take great care not to treat it as a
1653 // fall-through. It is much easier just to wrap the entire
1654 // try-statement in a statement block and put the labels there
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001655 Block* result =
1656 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001657 Target target(&this->target_stack_, result);
Steve Blocka7e24c12009-10-30 11:49:00 +00001658 TryStatement* statement = ParseTryStatement(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001659 if (result) result->AddStatement(statement, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00001660 return result;
1661 }
1662
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001663 case Token::FUNCTION: {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001664 // FunctionDeclaration is only allowed in the context of SourceElements
1665 // (Ecma 262 5th Edition, clause 14):
1666 // SourceElement:
1667 // Statement
1668 // FunctionDeclaration
1669 // Common language extension is to allow function declaration in place
1670 // of any statement. This language extension is disabled in strict mode.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001671 //
1672 // In Harmony mode, this case also handles the extension:
1673 // Statement:
1674 // GeneratorDeclaration
1675 if (strict_mode() == STRICT) {
1676 ReportMessageAt(scanner()->peek_location(), "strict_function");
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001677 *ok = false;
1678 return NULL;
1679 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001680 return ParseFunctionDeclaration(NULL, ok);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001681 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001682
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001683 case Token::CLASS:
1684 return ParseClassDeclaration(NULL, ok);
1685
Steve Blocka7e24c12009-10-30 11:49:00 +00001686 case Token::DEBUGGER:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001687 return ParseDebuggerStatement(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001688
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001689 case Token::VAR:
1690 case Token::CONST:
1691 return ParseVariableStatement(kStatement, NULL, ok);
1692
1693 case Token::LET:
1694 DCHECK(allow_harmony_scoping());
1695 if (strict_mode() == STRICT) {
1696 return ParseVariableStatement(kStatement, NULL, ok);
1697 }
1698 // Fall through.
Steve Blocka7e24c12009-10-30 11:49:00 +00001699 default:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001700 return ParseExpressionOrLabelledStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001701 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001702}
1703
1704
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001705VariableProxy* Parser::NewUnresolved(const AstRawString* name,
1706 VariableMode mode, Interface* interface) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001707 // If we are inside a function, a declaration of a var/const variable is a
1708 // truly local variable, and the scope of the variable is always the function
1709 // scope.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001710 // Let/const variables in harmony mode are always added to the immediately
1711 // enclosing scope.
1712 return DeclarationScope(mode)->NewUnresolved(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001713 factory(), name, interface, position());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001714}
1715
1716
1717void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1718 VariableProxy* proxy = declaration->proxy();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001719 DCHECK(proxy->raw_name() != NULL);
1720 const AstRawString* name = proxy->raw_name();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001721 VariableMode mode = declaration->mode();
1722 Scope* declaration_scope = DeclarationScope(mode);
1723 Variable* var = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001724
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001725 // If a suitable scope exists, then we can statically declare this
Steve Blocka7e24c12009-10-30 11:49:00 +00001726 // variable and also set its mode. In any case, a Declaration node
1727 // will be added to the scope so that the declaration can be added
1728 // to the corresponding activation frame at runtime if necessary.
1729 // For instance declarations inside an eval scope need to be added
1730 // to the calling function context.
Ben Murdoch257744e2011-11-30 15:57:28 +00001731 // Similarly, strict mode eval scope does not leak variable declarations to
1732 // the caller's scope so we declare all locals, too.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001733 if (declaration_scope->is_function_scope() ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001734 declaration_scope->is_strict_eval_scope() ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001735 declaration_scope->is_block_scope() ||
1736 declaration_scope->is_module_scope() ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001737 declaration_scope->is_global_scope()) {
1738 // Declare the variable in the declaration scope.
1739 // For the global scope, we have to check for collisions with earlier
1740 // (i.e., enclosing) global scopes, to maintain the illusion of a single
1741 // global scope.
1742 var = declaration_scope->is_global_scope()
1743 ? declaration_scope->Lookup(name)
1744 : declaration_scope->LookupLocal(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00001745 if (var == NULL) {
1746 // Declare the name.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001747 var = declaration_scope->DeclareLocal(name, mode,
1748 declaration->initialization(),
1749 kNotAssigned, proxy->interface());
1750 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
1751 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
1752 !declaration_scope->is_global_scope())) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001753 // The name was declared in this scope before; check for conflicting
1754 // re-declarations. We have a conflict if either of the declarations is
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001755 // not a var (in the global scope, we also have to ignore legacy const for
1756 // compatibility). There is similar code in runtime.cc in the Declare
1757 // functions. The function CheckConflictingVarDeclarations checks for
Ben Murdoch589d6972011-11-30 16:04:58 +00001758 // var and let bindings from different scopes whereas this is a check for
1759 // conflicting declarations within the same scope. This check also covers
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001760 // the special case
Ben Murdoch589d6972011-11-30 16:04:58 +00001761 //
1762 // function () { let x; { var x; } }
1763 //
1764 // because the var declaration is hoisted to the function scope where 'x'
1765 // is already bound.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001766 DCHECK(IsDeclaredVariableMode(var->mode()));
1767 if (allow_harmony_scoping() && strict_mode() == STRICT) {
1768 // In harmony we treat re-declarations as early errors. See
1769 // ES5 16 for a definition of early errors.
1770 ParserTraits::ReportMessage("var_redeclaration", name);
1771 *ok = false;
1772 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001773 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001774 Expression* expression = NewThrowTypeError(
1775 "var_redeclaration", name, declaration->position());
1776 declaration_scope->SetIllegalRedeclaration(expression);
1777 } else if (mode == VAR) {
1778 var->set_maybe_assigned();
Steve Blocka7e24c12009-10-30 11:49:00 +00001779 }
1780 }
1781
1782 // We add a declaration node for every declaration. The compiler
1783 // will only generate code if necessary. In particular, declarations
1784 // for inner local variables that do not represent functions won't
1785 // result in any generated code.
1786 //
1787 // Note that we always add an unresolved proxy even if it's not
1788 // used, simply because we don't know in this method (w/o extra
1789 // parameters) if the proxy is needed or not. The proxy will be
1790 // bound during variable resolution time unless it was pre-bound
1791 // below.
1792 //
1793 // WARNING: This will lead to multiple declaration nodes for the
1794 // same variable if it is declared several times. This is not a
1795 // semantic issue as long as we keep the source order, but it may be
1796 // a performance issue since it may lead to repeated
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001797 // RuntimeHidden_DeclareLookupSlot calls.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001798 declaration_scope->AddDeclaration(declaration);
Steve Blocka7e24c12009-10-30 11:49:00 +00001799
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001800 if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001801 // For global const variables we bind the proxy to a variable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001802 DCHECK(resolve); // should be set by all callers
Steve Blocka7e24c12009-10-30 11:49:00 +00001803 Variable::Kind kind = Variable::NORMAL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001804 var = new (zone())
1805 Variable(declaration_scope, name, mode, true, kind,
1806 kNeedsInitialization, kNotAssigned, proxy->interface());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001807 } else if (declaration_scope->is_eval_scope() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001808 declaration_scope->strict_mode() == SLOPPY) {
1809 // For variable declarations in a sloppy eval scope the proxy is bound
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001810 // to a lookup variable to force a dynamic declaration using the
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001811 // DeclareLookupSlot runtime function.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001812 Variable::Kind kind = Variable::NORMAL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001813 // TODO(sigurds) figure out if kNotAssigned is OK here
1814 var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
1815 declaration->initialization(), kNotAssigned,
1816 proxy->interface());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001817 var->AllocateTo(Variable::LOOKUP, -1);
1818 resolve = true;
Steve Blocka7e24c12009-10-30 11:49:00 +00001819 }
1820
1821 // If requested and we have a local variable, bind the proxy to the variable
1822 // at parse-time. This is used for functions (and consts) declared inside
1823 // statements: the corresponding function (or const) variable must be in the
1824 // function scope and not a statement-local scope, e.g. as provided with a
1825 // 'with' statement:
1826 //
1827 // with (obj) {
1828 // function f() {}
1829 // }
1830 //
1831 // which is translated into:
1832 //
1833 // with (obj) {
1834 // // in this case this is not: 'var f; f = function () {};'
1835 // var f = function () {};
1836 // }
1837 //
1838 // Note that if 'f' is accessed from inside the 'with' statement, it
1839 // will be allocated in the context (because we must be able to look
1840 // it up dynamically) but it will also be accessed statically, i.e.,
1841 // with a context slot index and a context chain length for this
1842 // initialization code. Thus, inside the 'with' statement, we need
1843 // both access to the static and the dynamic context chain; the
1844 // runtime needs to provide both.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001845 if (resolve && var != NULL) {
1846 proxy->BindTo(var);
Steve Blocka7e24c12009-10-30 11:49:00 +00001847
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001848 if (FLAG_harmony_modules) {
1849 bool ok;
1850#ifdef DEBUG
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001851 if (FLAG_print_interface_details) {
1852 PrintF("# Declare %.*s ", var->raw_name()->length(),
1853 var->raw_name()->raw_data());
1854 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001855#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001856 proxy->interface()->Unify(var->interface(), zone(), &ok);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001857 if (!ok) {
1858#ifdef DEBUG
1859 if (FLAG_print_interfaces) {
1860 PrintF("DECLARE TYPE ERROR\n");
1861 PrintF("proxy: ");
1862 proxy->interface()->Print();
1863 PrintF("var: ");
1864 var->interface()->Print();
1865 }
1866#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001867 ParserTraits::ReportMessage("module_type_error", name);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001868 }
1869 }
1870 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001871}
1872
1873
1874// Language extension which is only enabled for source files loaded
1875// through the API's extension mechanism. A native function
1876// declaration is resolved by looking up the function through a
1877// callback provided by the extension.
1878Statement* Parser::ParseNativeDeclaration(bool* ok) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001879 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001880 Expect(Token::FUNCTION, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001881 // Allow "eval" or "arguments" for backward compatibility.
1882 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00001883 Expect(Token::LPAREN, CHECK_OK);
1884 bool done = (peek() == Token::RPAREN);
1885 while (!done) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001886 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00001887 done = (peek() == Token::RPAREN);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001888 if (!done) {
1889 Expect(Token::COMMA, CHECK_OK);
1890 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001891 }
1892 Expect(Token::RPAREN, CHECK_OK);
1893 Expect(Token::SEMICOLON, CHECK_OK);
1894
Steve Blocka7e24c12009-10-30 11:49:00 +00001895 // Make sure that the function containing the native declaration
1896 // isn't lazily compiled. The extension structures are only
1897 // accessible while parsing the first time not when reparsing
1898 // because of lazy compilation.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001899 DeclarationScope(VAR)->ForceEagerCompilation();
Steve Blocka7e24c12009-10-30 11:49:00 +00001900
Steve Blocka7e24c12009-10-30 11:49:00 +00001901 // TODO(1240846): It's weird that native function declarations are
1902 // introduced dynamically when we meet their declarations, whereas
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001903 // other functions are set up when entering the surrounding scope.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001904 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001905 Declaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001906 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001907 Declare(declaration, true, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001908 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
1909 name, extension_, RelocInfo::kNoPosition);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001910 return factory()->NewExpressionStatement(
1911 factory()->NewAssignment(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001912 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
1913 pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00001914}
1915
1916
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001917Statement* Parser::ParseFunctionDeclaration(
1918 ZoneList<const AstRawString*>* names, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001919 // FunctionDeclaration ::
1920 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001921 // GeneratorDeclaration ::
1922 // 'function' '*' Identifier '(' FormalParameterListopt ')'
1923 // '{' FunctionBody '}'
Steve Blocka7e24c12009-10-30 11:49:00 +00001924 Expect(Token::FUNCTION, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001925 int pos = position();
1926 bool is_generator = Check(Token::MUL);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001927 bool is_strict_reserved = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001928 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001929 &is_strict_reserved, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001930 FunctionLiteral* fun =
1931 ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
1932 is_generator ? FunctionKind::kGeneratorFunction
1933 : FunctionKind::kNormalFunction,
1934 pos, FunctionLiteral::DECLARATION,
1935 FunctionLiteral::NORMAL_ARITY, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00001936 // Even if we're not at the top-level of the global or a function
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001937 // scope, we treat it as such and introduce the function with its
Steve Blocka7e24c12009-10-30 11:49:00 +00001938 // initial value upon entering the corresponding scope.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001939 // In ES6, a function behaves as a lexical binding, except in the
1940 // global scope, or the initial scope of eval or another function.
1941 VariableMode mode =
1942 allow_harmony_scoping() && strict_mode() == STRICT &&
1943 !(scope_->is_global_scope() || scope_->is_eval_scope() ||
1944 scope_->is_function_scope()) ? LET : VAR;
1945 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001946 Declaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001947 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001948 Declare(declaration, true, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001949 if (names) names->Add(name, zone());
1950 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00001951}
1952
1953
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001954Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
1955 bool* ok) {
1956 // ClassDeclaration ::
1957 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
1958 //
1959 // A ClassDeclaration
1960 //
1961 // class C { ... }
1962 //
1963 // has the same semantics as:
1964 //
1965 // let C = class C { ... };
1966 //
1967 // so rewrite it as such.
1968
1969 Expect(Token::CLASS, CHECK_OK);
1970 int pos = position();
1971 bool is_strict_reserved = false;
1972 const AstRawString* name =
1973 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1974 Expression* value = ParseClassLiteral(name, scanner()->location(),
1975 is_strict_reserved, pos, CHECK_OK);
1976
1977 Block* block = factory()->NewBlock(NULL, 1, true, pos);
1978 VariableMode mode = LET;
1979 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
1980 Declaration* declaration =
1981 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
1982 Declare(declaration, true, CHECK_OK);
1983
1984 Token::Value init_op = Token::INIT_LET;
1985 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
1986 block->AddStatement(
1987 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
1988 zone());
1989
1990 if (names) names->Add(name, zone());
1991 return block;
1992}
1993
1994
1995Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
1996 if (allow_harmony_scoping() && strict_mode() == STRICT) {
1997 return ParseScopedBlock(labels, ok);
1998 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001999
Steve Blocka7e24c12009-10-30 11:49:00 +00002000 // Block ::
2001 // '{' Statement* '}'
2002
2003 // Note that a Block does not introduce a new execution scope!
2004 // (ECMA-262, 3rd, 12.2)
2005 //
2006 // Construct block expecting 16 statements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002007 Block* result =
2008 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002009 Target target(&this->target_stack_, result);
Steve Blocka7e24c12009-10-30 11:49:00 +00002010 Expect(Token::LBRACE, CHECK_OK);
2011 while (peek() != Token::RBRACE) {
2012 Statement* stat = ParseStatement(NULL, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002013 if (stat && !stat->IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002014 result->AddStatement(stat, zone());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002015 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002016 }
2017 Expect(Token::RBRACE, CHECK_OK);
2018 return result;
2019}
2020
2021
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002022Block* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels,
2023 bool* ok) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002024 // The harmony mode uses block elements instead of statements.
2025 //
2026 // Block ::
2027 // '{' BlockElement* '}'
2028
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002029 // Construct block expecting 16 statements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002030 Block* body =
2031 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2032 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002033
2034 // Parse the statements and collect escaping labels.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002035 Expect(Token::LBRACE, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002036 block_scope->set_start_position(scanner()->location().beg_pos);
2037 { BlockState block_state(&scope_, block_scope);
2038 TargetCollector collector(zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002039 Target target(&this->target_stack_, &collector);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002040 Target target_body(&this->target_stack_, body);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002041
2042 while (peek() != Token::RBRACE) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002043 Statement* stat = ParseBlockElement(NULL, CHECK_OK);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002044 if (stat && !stat->IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002045 body->AddStatement(stat, zone());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002046 }
2047 }
2048 }
2049 Expect(Token::RBRACE, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002050 block_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch589d6972011-11-30 16:04:58 +00002051 block_scope = block_scope->FinalizeBlockScope();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002052 body->set_scope(block_scope);
Ben Murdoch589d6972011-11-30 16:04:58 +00002053 return body;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002054}
2055
2056
2057Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002058 ZoneList<const AstRawString*>* names,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002059 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002060 // VariableStatement ::
2061 // VariableDeclarations ';'
2062
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002063 const AstRawString* ignore;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002064 Block* result =
2065 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002066 ExpectSemicolon(CHECK_OK);
2067 return result;
2068}
2069
Steve Block44f0eee2011-05-26 01:26:41 +01002070
Steve Blocka7e24c12009-10-30 11:49:00 +00002071// If the variable declaration declares exactly one non-const
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002072// variable, then *out is set to that variable. In all other cases,
2073// *out is untouched; in particular, it is the caller's responsibility
Steve Blocka7e24c12009-10-30 11:49:00 +00002074// to initialize it properly. This mechanism is used for the parsing
2075// of 'for-in' loops.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002076Block* Parser::ParseVariableDeclarations(
2077 VariableDeclarationContext var_context,
2078 VariableDeclarationProperties* decl_props,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002079 ZoneList<const AstRawString*>* names,
2080 const AstRawString** out,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002081 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002082 // VariableDeclarations ::
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002083 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2084 //
2085 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2086 //
2087 // ConstDeclaration ::
2088 // const ConstBinding (',' ConstBinding)* ';'
2089 // ConstBinding ::
2090 // Identifier '=' AssignmentExpression
2091 //
2092 // TODO(ES6):
2093 // ConstBinding ::
2094 // BindingPattern '=' AssignmentExpression
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002095
2096 int pos = peek_position();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002097 VariableMode mode = VAR;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002098 // True if the binding needs initialization. 'let' and 'const' declared
2099 // bindings are created uninitialized by their declaration nodes and
2100 // need initialization. 'var' declared bindings are always initialized
2101 // immediately by their declaration nodes.
2102 bool needs_init = false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002103 bool is_const = false;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002104 Token::Value init_op = Token::INIT_VAR;
Steve Blocka7e24c12009-10-30 11:49:00 +00002105 if (peek() == Token::VAR) {
2106 Consume(Token::VAR);
2107 } else if (peek() == Token::CONST) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002108 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
2109 //
2110 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
2111 //
2112 // * It is a Syntax Error if the code that matches this production is not
2113 // contained in extended code.
2114 //
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002115 // However disallowing const in sloppy mode will break compatibility with
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002116 // existing pages. Therefore we keep allowing const with the old
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002117 // non-harmony semantics in sloppy mode.
Steve Blocka7e24c12009-10-30 11:49:00 +00002118 Consume(Token::CONST);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002119 switch (strict_mode()) {
2120 case SLOPPY:
2121 mode = CONST_LEGACY;
2122 init_op = Token::INIT_CONST_LEGACY;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002123 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002124 case STRICT:
2125 if (allow_harmony_scoping()) {
2126 if (var_context == kStatement) {
2127 // In strict mode 'const' declarations are only allowed in source
2128 // element positions.
2129 ReportMessage("unprotected_const");
2130 *ok = false;
2131 return NULL;
2132 }
2133 mode = CONST;
2134 init_op = Token::INIT_CONST;
2135 } else {
2136 ReportMessage("strict_const");
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002137 *ok = false;
2138 return NULL;
2139 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002140 }
2141 is_const = true;
2142 needs_init = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002143 } else if (peek() == Token::LET && strict_mode() == STRICT) {
2144 DCHECK(allow_harmony_scoping());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002145 Consume(Token::LET);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002146 if (var_context == kStatement) {
2147 // Let declarations are only allowed in source element positions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002148 ReportMessage("unprotected_let");
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002149 *ok = false;
2150 return NULL;
2151 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002152 mode = LET;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002153 needs_init = true;
2154 init_op = Token::INIT_LET;
Steve Blocka7e24c12009-10-30 11:49:00 +00002155 } else {
2156 UNREACHABLE(); // by current callers
2157 }
2158
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002159 Scope* declaration_scope = DeclarationScope(mode);
2160
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002161 // The scope of a var/const declared variable anywhere inside a function
Steve Blocka7e24c12009-10-30 11:49:00 +00002162 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002163 // transform a source-level var/const declaration into a (Function)
Steve Blocka7e24c12009-10-30 11:49:00 +00002164 // Scope declaration, and rewrite the source-level initialization into an
2165 // assignment statement. We use a block to collect multiple assignments.
2166 //
2167 // We mark the block as initializer block because we don't want the
2168 // rewriter to add a '.result' assignment to such a block (to get compliant
2169 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2170 // reasons when pretty-printing. Also, unless an assignment (initialization)
2171 // is inside an initializer block, it is ignored.
2172 //
2173 // Create new block with one expected declaration.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002174 Block* block = factory()->NewBlock(NULL, 1, true, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002175 int nvars = 0; // the number of variables declared
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002176 const AstRawString* name = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002177 do {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002178 if (fni_ != NULL) fni_->Enter();
2179
Steve Blocka7e24c12009-10-30 11:49:00 +00002180 // Parse variable name.
2181 if (nvars > 0) Consume(Token::COMMA);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002182 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002183 if (fni_ != NULL) fni_->PushVariableName(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00002184
2185 // Declare variable.
2186 // Note that we *always* must treat the initial value via a separate init
2187 // assignment for variables and constants because the value must be assigned
2188 // when the variable is encountered in the source. But the variable/constant
2189 // is declared (and set to 'undefined') upon entering the function within
2190 // which the variable or constant is declared. Only function variables have
2191 // an initial value in the declaration (because they are initialized upon
2192 // entering the function).
2193 //
2194 // If we have a const declaration, in an inner scope, the proxy is always
2195 // bound to the declared variable (independent of possibly surrounding with
2196 // statements).
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002197 // For let/const declarations in harmony mode, we can also immediately
2198 // pre-resolve the proxy because it resides in the same scope as the
2199 // declaration.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002200 Interface* interface =
2201 is_const ? Interface::NewConst() : Interface::NewValue();
2202 VariableProxy* proxy = NewUnresolved(name, mode, interface);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002203 Declaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002204 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002205 Declare(declaration, mode != VAR, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002206 nvars++;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002207 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002208 ReportMessage("too_many_variables");
Steve Block053d10c2011-06-13 19:13:29 +01002209 *ok = false;
2210 return NULL;
2211 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002212 if (names) names->Add(name, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002213
2214 // Parse initialization expression if present and/or needed. A
2215 // declaration of the form:
2216 //
2217 // var v = x;
2218 //
2219 // is syntactic sugar for:
2220 //
2221 // var v; v = x;
2222 //
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002223 // In particular, we need to re-lookup 'v' (in scope_, not
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002224 // declaration_scope) as it may be a different 'v' than the 'v' in the
2225 // declaration (e.g., if we are inside a 'with' statement or 'catch'
2226 // block).
Steve Blocka7e24c12009-10-30 11:49:00 +00002227 //
2228 // However, note that const declarations are different! A const
2229 // declaration of the form:
2230 //
2231 // const c = x;
2232 //
2233 // is *not* syntactic sugar for:
2234 //
2235 // const c; c = x;
2236 //
2237 // The "variable" c initialized to x is the same as the declared
2238 // one - there is no re-lookup (see the last parameter of the
2239 // Declare() call above).
2240
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002241 Scope* initialization_scope = is_const ? declaration_scope : scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002242 Expression* value = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002243 int pos = -1;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002244 // Harmony consts have non-optional initializers.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002245 if (peek() == Token::ASSIGN || mode == CONST) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002246 Expect(Token::ASSIGN, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002247 pos = position();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002248 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002249 // Don't infer if it is "a = function(){...}();"-like expression.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002250 if (fni_ != NULL &&
2251 value->AsCall() == NULL &&
2252 value->AsCallNew() == NULL) {
2253 fni_->Infer();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002254 } else {
2255 fni_->RemoveLastFunction();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002256 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002257 if (decl_props != NULL) *decl_props = kHasInitializers;
2258 }
2259
2260 // Record the end position of the initializer.
2261 if (proxy->var() != NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002262 proxy->var()->set_initializer_position(position());
Steve Blocka7e24c12009-10-30 11:49:00 +00002263 }
2264
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002265 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2266 if (value == NULL && needs_init) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002267 value = GetLiteralUndefined(position());
Steve Blocka7e24c12009-10-30 11:49:00 +00002268 }
2269
2270 // Global variable declarations must be compiled in a specific
2271 // way. When the script containing the global variable declaration
2272 // is entered, the global variable must be declared, so that if it
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002273 // doesn't exist (on the global object itself, see ES5 errata) it
Steve Blocka7e24c12009-10-30 11:49:00 +00002274 // gets created with an initial undefined value. This is handled
2275 // by the declarations part of the function representing the
2276 // top-level global code; see Runtime::DeclareGlobalVariable. If
2277 // it already exists (in the object or in a prototype), it is
2278 // *not* touched until the variable declaration statement is
2279 // executed.
2280 //
2281 // Executing the variable declaration statement will always
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002282 // guarantee to give the global object an own property.
2283 // This way, global variable declarations can shadow
Steve Blocka7e24c12009-10-30 11:49:00 +00002284 // properties in the prototype chain, but only after the variable
2285 // declaration statement has been executed. This is important in
2286 // browsers where the global object (window) has lots of
2287 // properties defined in prototype objects.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002288 if (initialization_scope->is_global_scope() &&
2289 !IsLexicalVariableMode(mode)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002290 // Compute the arguments for the runtime call.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002291 ZoneList<Expression*>* arguments =
2292 new(zone()) ZoneList<Expression*>(3, zone());
Ben Murdoch8b112d22011-06-08 16:22:53 +01002293 // We have at least 1 parameter.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002294 arguments->Add(factory()->NewStringLiteral(name, pos), zone());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002295 CallRuntime* initialize;
2296
2297 if (is_const) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002298 arguments->Add(value, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002299 value = NULL; // zap the value to avoid the unnecessary assignment
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002300
2301 // Construct the call to Runtime_InitializeConstGlobal
2302 // and add it to the initialization statement block.
2303 // Note that the function does different things depending on
2304 // the number of arguments (1 or 2).
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002305 initialize = factory()->NewCallRuntime(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002306 ast_value_factory()->initialize_const_global_string(),
2307 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), arguments,
2308 pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002309 } else {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002310 // Add strict mode.
2311 // We may want to pass singleton to avoid Literal allocations.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002312 StrictMode strict_mode = initialization_scope->strict_mode();
2313 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002314
2315 // Be careful not to assign a value to the global variable if
2316 // we're in a with. The initialization value should not
2317 // necessarily be stored in the global object in that case,
2318 // which is why we need to generate a separate assignment node.
2319 if (value != NULL && !inside_with()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002320 arguments->Add(value, zone());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002321 value = NULL; // zap the value to avoid the unnecessary assignment
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002322 // Construct the call to Runtime_InitializeVarGlobal
2323 // and add it to the initialization statement block.
2324 initialize = factory()->NewCallRuntime(
2325 ast_value_factory()->initialize_var_global_string(),
2326 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), arguments,
2327 pos);
2328 } else {
2329 initialize = NULL;
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002330 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002331 }
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002332
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002333 if (initialize != NULL) {
2334 block->AddStatement(factory()->NewExpressionStatement(
2335 initialize, RelocInfo::kNoPosition),
2336 zone());
2337 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002338 } else if (needs_init) {
2339 // Constant initializations always assign to the declared constant which
2340 // is always at the function scope level. This is only relevant for
2341 // dynamically looked-up variables and constants (the start context for
2342 // constant lookups is always the function context, while it is the top
2343 // context for var declared variables). Sigh...
2344 // For 'let' and 'const' declared variables in harmony mode the
2345 // initialization also always assigns to the declared variable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002346 DCHECK(proxy != NULL);
2347 DCHECK(proxy->var() != NULL);
2348 DCHECK(value != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002349 Assignment* assignment =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002350 factory()->NewAssignment(init_op, proxy, value, pos);
2351 block->AddStatement(
2352 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2353 zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002354 value = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002355 }
2356
Ben Murdoch589d6972011-11-30 16:04:58 +00002357 // Add an assignment node to the initialization statement block if we still
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002358 // have a pending initialization value.
Steve Blocka7e24c12009-10-30 11:49:00 +00002359 if (value != NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002360 DCHECK(mode == VAR);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002361 // 'var' initializations are simply assignments (with all the consequences
2362 // if they are inside a 'with' statement - they may change a 'with' object
2363 // property).
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002364 VariableProxy* proxy =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002365 initialization_scope->NewUnresolved(factory(), name, interface);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002366 Assignment* assignment =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002367 factory()->NewAssignment(init_op, proxy, value, pos);
2368 block->AddStatement(
2369 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2370 zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002371 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002372
2373 if (fni_ != NULL) fni_->Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +00002374 } while (peek() == Token::COMMA);
2375
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002376 // If there was a single non-const declaration, return it in the output
2377 // parameter for possible use by for/in.
2378 if (nvars == 1 && !is_const) {
2379 *out = name;
Steve Blocka7e24c12009-10-30 11:49:00 +00002380 }
2381
2382 return block;
2383}
2384
2385
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002386static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2387 const AstRawString* label) {
2388 DCHECK(label != NULL);
2389 if (labels != NULL) {
2390 for (int i = labels->length(); i-- > 0; ) {
2391 if (labels->at(i) == label) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002392 return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002393 }
2394 }
2395 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002396 return false;
2397}
2398
2399
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002400Statement* Parser::ParseExpressionOrLabelledStatement(
2401 ZoneList<const AstRawString*>* labels, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002402 // ExpressionStatement | LabelledStatement ::
2403 // Expression ';'
2404 // Identifier ':' Statement
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002405 int pos = peek_position();
Steve Block1e0659c2011-05-24 12:43:12 +01002406 bool starts_with_idenfifier = peek_any_identifier();
Steve Blocka7e24c12009-10-30 11:49:00 +00002407 Expression* expr = ParseExpression(true, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002408 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
Steve Blocka7e24c12009-10-30 11:49:00 +00002409 expr->AsVariableProxy() != NULL &&
2410 !expr->AsVariableProxy()->is_this()) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002411 // Expression is a single identifier, and not, e.g., a parenthesized
2412 // identifier.
Steve Blocka7e24c12009-10-30 11:49:00 +00002413 VariableProxy* var = expr->AsVariableProxy();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002414 const AstRawString* label = var->raw_name();
Steve Blocka7e24c12009-10-30 11:49:00 +00002415 // TODO(1240780): We don't check for redeclaration of labels
2416 // during preparsing since keeping track of the set of active
2417 // labels requires nontrivial changes to the way scopes are
2418 // structured. However, these are probably changes we want to
2419 // make later anyway so we should go back and fix this then.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002420 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002421 ParserTraits::ReportMessage("label_redeclaration", label);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002422 *ok = false;
2423 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002424 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002425 if (labels == NULL) {
2426 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2427 }
2428 labels->Add(label, zone());
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002429 // Remove the "ghost" variable that turned out to be a label
2430 // from the top scope. This way, we don't try to resolve it
2431 // during the scope processing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002432 scope_->RemoveUnresolved(var);
Steve Blocka7e24c12009-10-30 11:49:00 +00002433 Expect(Token::COLON, CHECK_OK);
2434 return ParseStatement(labels, ok);
2435 }
2436
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002437 // If we have an extension, we allow a native function declaration.
2438 // A native function declaration starts with "native function" with
2439 // no line-terminator between the two words.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002440 if (extension_ != NULL && peek() == Token::FUNCTION &&
2441 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002442 expr->AsVariableProxy() != NULL &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002443 expr->AsVariableProxy()->raw_name() ==
2444 ast_value_factory()->native_string() &&
2445 !scanner()->literal_contains_escapes()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002446 return ParseNativeDeclaration(ok);
2447 }
2448
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002449 // Parsed expression statement, or the context-sensitive 'module' keyword.
2450 // Only expect semicolon in the former case.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002451 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER ||
2452 scanner()->HasAnyLineTerminatorBeforeNext() ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002453 expr->AsVariableProxy() == NULL ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002454 expr->AsVariableProxy()->raw_name() !=
2455 ast_value_factory()->module_string() ||
2456 scanner()->literal_contains_escapes()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002457 ExpectSemicolon(CHECK_OK);
2458 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002459 return factory()->NewExpressionStatement(expr, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002460}
2461
2462
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002463IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2464 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002465 // IfStatement ::
2466 // 'if' '(' Expression ')' Statement ('else' Statement)?
2467
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002468 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002469 Expect(Token::IF, CHECK_OK);
2470 Expect(Token::LPAREN, CHECK_OK);
2471 Expression* condition = ParseExpression(true, CHECK_OK);
2472 Expect(Token::RPAREN, CHECK_OK);
2473 Statement* then_statement = ParseStatement(labels, CHECK_OK);
2474 Statement* else_statement = NULL;
2475 if (peek() == Token::ELSE) {
2476 Next();
2477 else_statement = ParseStatement(labels, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002478 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002479 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00002480 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002481 return factory()->NewIfStatement(
2482 condition, then_statement, else_statement, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002483}
2484
2485
2486Statement* Parser::ParseContinueStatement(bool* ok) {
2487 // ContinueStatement ::
2488 // 'continue' Identifier? ';'
2489
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002490 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002491 Expect(Token::CONTINUE, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002492 const AstRawString* label = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002493 Token::Value tok = peek();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002494 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
Steve Blocka7e24c12009-10-30 11:49:00 +00002495 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002496 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2497 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002498 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002499 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002500 if (target == NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002501 // Illegal continue statement.
2502 const char* message = "illegal_continue";
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002503 if (label != NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002504 message = "unknown_label";
Ben Murdochb8e0da22011-05-16 14:20:40 +01002505 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002506 ParserTraits::ReportMessage(message, label);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002507 *ok = false;
2508 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002509 }
2510 ExpectSemicolon(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002511 return factory()->NewContinueStatement(target, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002512}
2513
2514
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002515Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2516 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002517 // BreakStatement ::
2518 // 'break' Identifier? ';'
2519
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002520 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002521 Expect(Token::BREAK, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002522 const AstRawString* label = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002523 Token::Value tok = peek();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002524 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
Steve Blocka7e24c12009-10-30 11:49:00 +00002525 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002526 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2527 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002528 }
2529 // Parse labeled break statements that target themselves into
2530 // empty statements, e.g. 'l1: l2: l3: break l2;'
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002531 if (label != NULL && ContainsLabel(labels, label)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002532 ExpectSemicolon(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002533 return factory()->NewEmptyStatement(pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002534 }
2535 BreakableStatement* target = NULL;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002536 target = LookupBreakTarget(label, CHECK_OK);
2537 if (target == NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002538 // Illegal break statement.
2539 const char* message = "illegal_break";
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002540 if (label != NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002541 message = "unknown_label";
Ben Murdochb8e0da22011-05-16 14:20:40 +01002542 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002543 ParserTraits::ReportMessage(message, label);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002544 *ok = false;
2545 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002546 }
2547 ExpectSemicolon(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002548 return factory()->NewBreakStatement(target, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002549}
2550
2551
2552Statement* Parser::ParseReturnStatement(bool* ok) {
2553 // ReturnStatement ::
2554 // 'return' Expression? ';'
2555
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002556 // Consume the return token. It is necessary to do that before
Steve Blocka7e24c12009-10-30 11:49:00 +00002557 // reporting any errors on it, because of the way errors are
2558 // reported (underlining).
2559 Expect(Token::RETURN, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002560 Scanner::Location loc = scanner()->location();
Steve Blocka7e24c12009-10-30 11:49:00 +00002561
Ben Murdoch692be652012-01-10 18:47:50 +00002562 Token::Value tok = peek();
2563 Statement* result;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002564 Expression* return_value;
2565 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
Ben Murdoch692be652012-01-10 18:47:50 +00002566 tok == Token::SEMICOLON ||
2567 tok == Token::RBRACE ||
2568 tok == Token::EOS) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002569 return_value = GetLiteralUndefined(position());
Ben Murdoch692be652012-01-10 18:47:50 +00002570 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002571 return_value = ParseExpression(true, CHECK_OK);
2572 }
2573 ExpectSemicolon(CHECK_OK);
2574 if (is_generator()) {
2575 Expression* generator = factory()->NewVariableProxy(
2576 function_state_->generator_object_variable());
2577 Expression* yield = factory()->NewYield(
2578 generator, return_value, Yield::kFinal, loc.beg_pos);
2579 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2580 } else {
2581 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
Ben Murdoch692be652012-01-10 18:47:50 +00002582 }
2583
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002584 Scope* decl_scope = scope_->DeclarationScope();
2585 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) {
2586 ReportMessageAt(loc, "illegal_return");
2587 *ok = false;
2588 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002589 }
Ben Murdoch692be652012-01-10 18:47:50 +00002590 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002591}
2592
2593
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002594Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2595 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002596 // WithStatement ::
2597 // 'with' '(' Expression ')' Statement
2598
2599 Expect(Token::WITH, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002600 int pos = position();
Steve Block1e0659c2011-05-24 12:43:12 +01002601
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002602 if (strict_mode() == STRICT) {
2603 ReportMessage("strict_mode_with");
Steve Block1e0659c2011-05-24 12:43:12 +01002604 *ok = false;
2605 return NULL;
2606 }
2607
Steve Blocka7e24c12009-10-30 11:49:00 +00002608 Expect(Token::LPAREN, CHECK_OK);
2609 Expression* expr = ParseExpression(true, CHECK_OK);
2610 Expect(Token::RPAREN, CHECK_OK);
2611
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002612 scope_->DeclarationScope()->RecordWithStatement();
2613 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002614 Statement* stmt;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002615 { BlockState block_state(&scope_, with_scope);
2616 with_scope->set_start_position(scanner()->peek_location().beg_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002617 stmt = ParseStatement(labels, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002618 with_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002619 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002620 return factory()->NewWithStatement(with_scope, expr, stmt, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002621}
2622
2623
2624CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2625 // CaseClause ::
2626 // 'case' Expression ':' Statement*
2627 // 'default' ':' Statement*
2628
2629 Expression* label = NULL; // NULL expression indicates default case
2630 if (peek() == Token::CASE) {
2631 Expect(Token::CASE, CHECK_OK);
2632 label = ParseExpression(true, CHECK_OK);
2633 } else {
2634 Expect(Token::DEFAULT, CHECK_OK);
2635 if (*default_seen_ptr) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002636 ReportMessage("multiple_defaults_in_switch");
Steve Blocka7e24c12009-10-30 11:49:00 +00002637 *ok = false;
2638 return NULL;
2639 }
2640 *default_seen_ptr = true;
2641 }
2642 Expect(Token::COLON, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002643 int pos = position();
2644 ZoneList<Statement*>* statements =
2645 new(zone()) ZoneList<Statement*>(5, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002646 while (peek() != Token::CASE &&
2647 peek() != Token::DEFAULT &&
2648 peek() != Token::RBRACE) {
2649 Statement* stat = ParseStatement(NULL, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002650 statements->Add(stat, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002651 }
2652
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002653 return factory()->NewCaseClause(label, statements, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002654}
2655
2656
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002657SwitchStatement* Parser::ParseSwitchStatement(
2658 ZoneList<const AstRawString*>* labels, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002659 // SwitchStatement ::
2660 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2661
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002662 SwitchStatement* statement =
2663 factory()->NewSwitchStatement(labels, peek_position());
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002664 Target target(&this->target_stack_, statement);
Steve Blocka7e24c12009-10-30 11:49:00 +00002665
2666 Expect(Token::SWITCH, CHECK_OK);
2667 Expect(Token::LPAREN, CHECK_OK);
2668 Expression* tag = ParseExpression(true, CHECK_OK);
2669 Expect(Token::RPAREN, CHECK_OK);
2670
2671 bool default_seen = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002672 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002673 Expect(Token::LBRACE, CHECK_OK);
2674 while (peek() != Token::RBRACE) {
2675 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002676 cases->Add(clause, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002677 }
2678 Expect(Token::RBRACE, CHECK_OK);
2679
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002680 if (statement) statement->Initialize(tag, cases);
Steve Blocka7e24c12009-10-30 11:49:00 +00002681 return statement;
2682}
2683
2684
2685Statement* Parser::ParseThrowStatement(bool* ok) {
2686 // ThrowStatement ::
2687 // 'throw' Expression ';'
2688
2689 Expect(Token::THROW, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002690 int pos = position();
2691 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2692 ReportMessage("newline_after_throw");
Steve Blocka7e24c12009-10-30 11:49:00 +00002693 *ok = false;
2694 return NULL;
2695 }
2696 Expression* exception = ParseExpression(true, CHECK_OK);
2697 ExpectSemicolon(CHECK_OK);
2698
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002699 return factory()->NewExpressionStatement(
2700 factory()->NewThrow(exception, pos), pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002701}
2702
2703
2704TryStatement* Parser::ParseTryStatement(bool* ok) {
2705 // TryStatement ::
2706 // 'try' Block Catch
2707 // 'try' Block Finally
2708 // 'try' Block Catch Finally
2709 //
2710 // Catch ::
2711 // 'catch' '(' Identifier ')' Block
2712 //
2713 // Finally ::
2714 // 'finally' Block
2715
2716 Expect(Token::TRY, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002717 int pos = position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002718
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002719 TargetCollector try_collector(zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002720 Block* try_block;
2721
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002722 { Target target(&this->target_stack_, &try_collector);
Steve Blocka7e24c12009-10-30 11:49:00 +00002723 try_block = ParseBlock(NULL, CHECK_OK);
2724 }
2725
Steve Blocka7e24c12009-10-30 11:49:00 +00002726 Token::Value tok = peek();
2727 if (tok != Token::CATCH && tok != Token::FINALLY) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002728 ReportMessage("no_catch_or_finally");
Steve Blocka7e24c12009-10-30 11:49:00 +00002729 *ok = false;
2730 return NULL;
2731 }
2732
2733 // If we can break out from the catch block and there is a finally block,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002734 // then we will need to collect escaping targets from the catch
2735 // block. Since we don't know yet if there will be a finally block, we
2736 // always collect the targets.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002737 TargetCollector catch_collector(zone());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002738 Scope* catch_scope = NULL;
2739 Variable* catch_variable = NULL;
2740 Block* catch_block = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002741 const AstRawString* name = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002742 if (tok == Token::CATCH) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002743 Consume(Token::CATCH);
2744
2745 Expect(Token::LPAREN, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002746 catch_scope = NewScope(scope_, CATCH_SCOPE);
2747 catch_scope->set_start_position(scanner()->location().beg_pos);
2748 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01002749
Steve Blocka7e24c12009-10-30 11:49:00 +00002750 Expect(Token::RPAREN, CHECK_OK);
2751
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002752 Target target(&this->target_stack_, &catch_collector);
2753 VariableMode mode =
2754 allow_harmony_scoping() && strict_mode() == STRICT ? LET : VAR;
2755 catch_variable = catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
2756 BlockState block_state(&scope_, catch_scope);
2757 catch_block = ParseBlock(NULL, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002758
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002759 catch_scope->set_end_position(scanner()->location().end_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002760 tok = peek();
2761 }
2762
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002763 Block* finally_block = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002764 DCHECK(tok == Token::FINALLY || catch_block != NULL);
2765 if (tok == Token::FINALLY) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002766 Consume(Token::FINALLY);
Steve Blocka7e24c12009-10-30 11:49:00 +00002767 finally_block = ParseBlock(NULL, CHECK_OK);
2768 }
2769
2770 // Simplify the AST nodes by converting:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002771 // 'try B0 catch B1 finally B2'
Steve Blocka7e24c12009-10-30 11:49:00 +00002772 // to:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002773 // 'try { try B0 catch B1 } finally B2'
Steve Blocka7e24c12009-10-30 11:49:00 +00002774
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002775 if (catch_block != NULL && finally_block != NULL) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002776 // If we have both, create an inner try/catch.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002777 DCHECK(catch_scope != NULL && catch_variable != NULL);
2778 int index = function_state_->NextHandlerIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002779 TryCatchStatement* statement = factory()->NewTryCatchStatement(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002780 index, try_block, catch_scope, catch_variable, catch_block,
2781 RelocInfo::kNoPosition);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002782 statement->set_escaping_targets(try_collector.targets());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002783 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
2784 try_block->AddStatement(statement, zone());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002785 catch_block = NULL; // Clear to indicate it's been handled.
Steve Blocka7e24c12009-10-30 11:49:00 +00002786 }
2787
2788 TryStatement* result = NULL;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002789 if (catch_block != NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002790 DCHECK(finally_block == NULL);
2791 DCHECK(catch_scope != NULL && catch_variable != NULL);
2792 int index = function_state_->NextHandlerIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002793 result = factory()->NewTryCatchStatement(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002794 index, try_block, catch_scope, catch_variable, catch_block, pos);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002795 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002796 DCHECK(finally_block != NULL);
2797 int index = function_state_->NextHandlerIndex();
2798 result = factory()->NewTryFinallyStatement(
2799 index, try_block, finally_block, pos);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002800 // Combine the jump targets of the try block and the possible catch block.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002801 try_collector.targets()->AddAll(*catch_collector.targets(), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002802 }
2803
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002804 result->set_escaping_targets(try_collector.targets());
Steve Blocka7e24c12009-10-30 11:49:00 +00002805 return result;
2806}
2807
2808
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002809DoWhileStatement* Parser::ParseDoWhileStatement(
2810 ZoneList<const AstRawString*>* labels, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002811 // DoStatement ::
2812 // 'do' Statement 'while' '(' Expression ')' ';'
2813
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002814 DoWhileStatement* loop =
2815 factory()->NewDoWhileStatement(labels, peek_position());
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002816 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002817
2818 Expect(Token::DO, CHECK_OK);
2819 Statement* body = ParseStatement(NULL, CHECK_OK);
2820 Expect(Token::WHILE, CHECK_OK);
2821 Expect(Token::LPAREN, CHECK_OK);
Steve Blockd0582a62009-12-15 09:54:21 +00002822
Steve Blocka7e24c12009-10-30 11:49:00 +00002823 Expression* cond = ParseExpression(true, CHECK_OK);
2824 Expect(Token::RPAREN, CHECK_OK);
2825
2826 // Allow do-statements to be terminated with and without
2827 // semi-colons. This allows code such as 'do;while(0)return' to
2828 // parse, which would not be the case if we had used the
2829 // ExpectSemicolon() functionality here.
2830 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2831
Steve Block3ce2e202009-11-05 08:53:23 +00002832 if (loop != NULL) loop->Initialize(cond, body);
Steve Blocka7e24c12009-10-30 11:49:00 +00002833 return loop;
2834}
2835
2836
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002837WhileStatement* Parser::ParseWhileStatement(
2838 ZoneList<const AstRawString*>* labels, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002839 // WhileStatement ::
2840 // 'while' '(' Expression ')' Statement
2841
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002842 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002843 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002844
2845 Expect(Token::WHILE, CHECK_OK);
2846 Expect(Token::LPAREN, CHECK_OK);
2847 Expression* cond = ParseExpression(true, CHECK_OK);
2848 Expect(Token::RPAREN, CHECK_OK);
2849 Statement* body = ParseStatement(NULL, CHECK_OK);
2850
Steve Block3ce2e202009-11-05 08:53:23 +00002851 if (loop != NULL) loop->Initialize(cond, body);
Steve Blocka7e24c12009-10-30 11:49:00 +00002852 return loop;
2853}
2854
2855
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002856bool Parser::CheckInOrOf(bool accept_OF,
2857 ForEachStatement::VisitMode* visit_mode) {
2858 if (Check(Token::IN)) {
2859 *visit_mode = ForEachStatement::ENUMERATE;
2860 return true;
2861 } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) {
2862 *visit_mode = ForEachStatement::ITERATE;
2863 return true;
2864 }
2865 return false;
2866}
2867
2868
2869void Parser::InitializeForEachStatement(ForEachStatement* stmt,
2870 Expression* each,
2871 Expression* subject,
2872 Statement* body) {
2873 ForOfStatement* for_of = stmt->AsForOfStatement();
2874
2875 if (for_of != NULL) {
2876 Variable* iterator = scope_->DeclarationScope()->NewTemporary(
2877 ast_value_factory()->dot_iterator_string());
2878 Variable* result = scope_->DeclarationScope()->NewTemporary(
2879 ast_value_factory()->dot_result_string());
2880
2881 Expression* assign_iterator;
2882 Expression* next_result;
2883 Expression* result_done;
2884 Expression* assign_each;
2885
2886 // var iterator = subject[Symbol.iterator]();
2887 assign_iterator = factory()->NewAssignment(
2888 Token::ASSIGN, factory()->NewVariableProxy(iterator),
2889 GetIterator(subject, factory()), RelocInfo::kNoPosition);
2890
2891 // var result = iterator.next();
2892 {
2893 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2894 Expression* next_literal = factory()->NewStringLiteral(
2895 ast_value_factory()->next_string(), RelocInfo::kNoPosition);
2896 Expression* next_property = factory()->NewProperty(
2897 iterator_proxy, next_literal, RelocInfo::kNoPosition);
2898 ZoneList<Expression*>* next_arguments =
2899 new(zone()) ZoneList<Expression*>(0, zone());
2900 Expression* next_call = factory()->NewCall(
2901 next_property, next_arguments, RelocInfo::kNoPosition);
2902 Expression* result_proxy = factory()->NewVariableProxy(result);
2903 next_result = factory()->NewAssignment(
2904 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition);
2905 }
2906
2907 // result.done
2908 {
2909 Expression* done_literal = factory()->NewStringLiteral(
2910 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
2911 Expression* result_proxy = factory()->NewVariableProxy(result);
2912 result_done = factory()->NewProperty(
2913 result_proxy, done_literal, RelocInfo::kNoPosition);
2914 }
2915
2916 // each = result.value
2917 {
2918 Expression* value_literal = factory()->NewStringLiteral(
2919 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
2920 Expression* result_proxy = factory()->NewVariableProxy(result);
2921 Expression* result_value = factory()->NewProperty(
2922 result_proxy, value_literal, RelocInfo::kNoPosition);
2923 assign_each = factory()->NewAssignment(
2924 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition);
2925 }
2926
2927 for_of->Initialize(each, subject, body,
2928 assign_iterator,
2929 next_result,
2930 result_done,
2931 assign_each);
2932 } else {
2933 stmt->Initialize(each, subject, body);
2934 }
2935}
2936
2937
2938Statement* Parser::DesugarLetBindingsInForStatement(
2939 Scope* inner_scope, ZoneList<const AstRawString*>* names,
2940 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2941 Statement* body, bool* ok) {
2942 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are
2943 // copied into a new environment. After copying, the "next" statement of the
2944 // loop is executed to update the loop variables. The loop condition is
2945 // checked and the loop body is executed.
2946 //
2947 // We rewrite a for statement of the form
2948 //
2949 // for (let x = i; cond; next) body
2950 //
2951 // into
2952 //
2953 // {
2954 // let x = i;
2955 // temp_x = x;
2956 // flag = 1;
2957 // for (;;) {
2958 // let x = temp_x;
2959 // if (flag == 1) {
2960 // flag = 0;
2961 // } else {
2962 // next;
2963 // }
2964 // if (cond) {
2965 // <empty>
2966 // } else {
2967 // break;
2968 // }
2969 // b
2970 // temp_x = x;
2971 // }
2972 // }
2973
2974 DCHECK(names->length() > 0);
2975 Scope* for_scope = scope_;
2976 ZoneList<Variable*> temps(names->length(), zone());
2977
2978 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
2979 RelocInfo::kNoPosition);
2980 outer_block->AddStatement(init, zone());
2981
2982 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2983
2984 // For each let variable x:
2985 // make statement: temp_x = x.
2986 for (int i = 0; i < names->length(); i++) {
2987 VariableProxy* proxy =
2988 NewUnresolved(names->at(i), LET, Interface::NewValue());
2989 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name);
2990 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2991 Assignment* assignment = factory()->NewAssignment(
2992 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
2993 Statement* assignment_statement = factory()->NewExpressionStatement(
2994 assignment, RelocInfo::kNoPosition);
2995 outer_block->AddStatement(assignment_statement, zone());
2996 temps.Add(temp, zone());
2997 }
2998
2999 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
3000 // Make statement: flag = 1.
3001 {
3002 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3003 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3004 Assignment* assignment = factory()->NewAssignment(
3005 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3006 Statement* assignment_statement = factory()->NewExpressionStatement(
3007 assignment, RelocInfo::kNoPosition);
3008 outer_block->AddStatement(assignment_statement, zone());
3009 }
3010
3011 outer_block->AddStatement(loop, zone());
3012 outer_block->set_scope(for_scope);
3013 scope_ = inner_scope;
3014
3015 Block* inner_block = factory()->NewBlock(NULL, 2 * names->length() + 3,
3016 false, RelocInfo::kNoPosition);
3017 int pos = scanner()->location().beg_pos;
3018 ZoneList<Variable*> inner_vars(names->length(), zone());
3019
3020 // For each let variable x:
3021 // make statement: let x = temp_x.
3022 for (int i = 0; i < names->length(); i++) {
3023 VariableProxy* proxy =
3024 NewUnresolved(names->at(i), LET, Interface::NewValue());
3025 Declaration* declaration =
3026 factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
3027 Declare(declaration, true, CHECK_OK);
3028 inner_vars.Add(declaration->proxy()->var(), zone());
3029 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3030 Assignment* assignment = factory()->NewAssignment(
3031 Token::INIT_LET, proxy, temp_proxy, pos);
3032 Statement* assignment_statement = factory()->NewExpressionStatement(
3033 assignment, pos);
3034 proxy->var()->set_initializer_position(pos);
3035 inner_block->AddStatement(assignment_statement, zone());
3036 }
3037
3038 // Make statement: if (flag == 1) { flag = 0; } else { next; }.
3039 if (next) {
3040 Expression* compare = NULL;
3041 // Make compare expresion: flag == 1.
3042 {
3043 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3044 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3045 compare = factory()->NewCompareOperation(
3046 Token::EQ, flag_proxy, const1, pos);
3047 }
3048 Statement* clear_flag = NULL;
3049 // Make statement: flag = 0.
3050 {
3051 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3052 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3053 Assignment* assignment = factory()->NewAssignment(
3054 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition);
3055 clear_flag = factory()->NewExpressionStatement(assignment, pos);
3056 }
3057 Statement* clear_flag_or_next = factory()->NewIfStatement(
3058 compare, clear_flag, next, RelocInfo::kNoPosition);
3059 inner_block->AddStatement(clear_flag_or_next, zone());
3060 }
3061
3062
3063 // Make statement: if (cond) { } else { break; }.
3064 if (cond) {
3065 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3066 BreakableStatement* t = LookupBreakTarget(NULL, CHECK_OK);
3067 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition);
3068 Statement* if_not_cond_break = factory()->NewIfStatement(
3069 cond, empty, stop, cond->position());
3070 inner_block->AddStatement(if_not_cond_break, zone());
3071 }
3072
3073 inner_block->AddStatement(body, zone());
3074
3075 // For each let variable x:
3076 // make statement: temp_x = x;
3077 for (int i = 0; i < names->length(); i++) {
3078 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3079 int pos = scanner()->location().end_pos;
3080 VariableProxy* proxy = factory()->NewVariableProxy(inner_vars.at(i), pos);
3081 Assignment* assignment = factory()->NewAssignment(
3082 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3083 Statement* assignment_statement = factory()->NewExpressionStatement(
3084 assignment, RelocInfo::kNoPosition);
3085 inner_block->AddStatement(assignment_statement, zone());
3086 }
3087
3088 inner_scope->set_end_position(scanner()->location().end_pos);
3089 inner_block->set_scope(inner_scope);
3090 scope_ = for_scope;
3091
3092 loop->Initialize(NULL, NULL, NULL, inner_block);
3093 return outer_block;
3094}
3095
3096
3097Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3098 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003099 // ForStatement ::
3100 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3101
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003102 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00003103 Statement* init = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003104 ZoneList<const AstRawString*> let_bindings(1, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00003105
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003106 // Create an in-between scope for let-bound iteration variables.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003107 Scope* saved_scope = scope_;
3108 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3109 scope_ = for_scope;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003110
Steve Blocka7e24c12009-10-30 11:49:00 +00003111 Expect(Token::FOR, CHECK_OK);
3112 Expect(Token::LPAREN, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003113 for_scope->set_start_position(scanner()->location().beg_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00003114 if (peek() != Token::SEMICOLON) {
3115 if (peek() == Token::VAR || peek() == Token::CONST) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003116 bool is_const = peek() == Token::CONST;
3117 const AstRawString* name = NULL;
3118 VariableDeclarationProperties decl_props = kHasNoInitializers;
Steve Blocka7e24c12009-10-30 11:49:00 +00003119 Block* variable_statement =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003120 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
3121 CHECK_OK);
3122 bool accept_OF = decl_props == kHasNoInitializers;
3123 ForEachStatement::VisitMode mode;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003124
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003125 if (name != NULL && CheckInOrOf(accept_OF, &mode)) {
3126 Interface* interface =
3127 is_const ? Interface::NewConst() : Interface::NewValue();
3128 ForEachStatement* loop =
3129 factory()->NewForEachStatement(mode, labels, pos);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003130 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00003131
Steve Blocka7e24c12009-10-30 11:49:00 +00003132 Expression* enumerable = ParseExpression(true, CHECK_OK);
3133 Expect(Token::RPAREN, CHECK_OK);
3134
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003135 VariableProxy* each =
3136 scope_->NewUnresolved(factory(), name, interface);
Steve Blocka7e24c12009-10-30 11:49:00 +00003137 Statement* body = ParseStatement(NULL, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003138 InitializeForEachStatement(loop, each, enumerable, body);
3139 Block* result =
3140 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3141 result->AddStatement(variable_statement, zone());
3142 result->AddStatement(loop, zone());
3143 scope_ = saved_scope;
3144 for_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003145 for_scope = for_scope->FinalizeBlockScope();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003146 DCHECK(for_scope == NULL);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003147 // Parsed for-in loop w/ variable/const declaration.
3148 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00003149 } else {
3150 init = variable_statement;
3151 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003152 } else if (peek() == Token::LET && strict_mode() == STRICT) {
3153 DCHECK(allow_harmony_scoping());
3154 const AstRawString* name = NULL;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003155 VariableDeclarationProperties decl_props = kHasNoInitializers;
3156 Block* variable_statement =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003157 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings,
3158 &name, CHECK_OK);
3159 bool accept_IN = name != NULL && decl_props != kHasInitializers;
3160 bool accept_OF = decl_props == kHasNoInitializers;
3161 ForEachStatement::VisitMode mode;
3162
3163 if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003164 // Rewrite a for-in statement of the form
3165 //
3166 // for (let x in e) b
3167 //
3168 // into
3169 //
3170 // <let x' be a temporary variable>
3171 // for (x' in e) {
3172 // let x;
3173 // x = x';
3174 // b;
3175 // }
Steve Blocka7e24c12009-10-30 11:49:00 +00003176
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003177 // TODO(keuchel): Move the temporary variable to the block scope, after
3178 // implementing stack allocated block scoped variables.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003179 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3180 ast_value_factory()->dot_for_string());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003181 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003182 ForEachStatement* loop =
3183 factory()->NewForEachStatement(mode, labels, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003184 Target target(&this->target_stack_, loop);
3185
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003186 // The expression does not see the loop variable.
3187 scope_ = saved_scope;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003188 Expression* enumerable = ParseExpression(true, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003189 scope_ = for_scope;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003190 Expect(Token::RPAREN, CHECK_OK);
3191
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003192 VariableProxy* each =
3193 scope_->NewUnresolved(factory(), name, Interface::NewValue());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003194 Statement* body = ParseStatement(NULL, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003195 Block* body_block =
3196 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003197 Assignment* assignment = factory()->NewAssignment(
3198 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003199 Statement* assignment_statement = factory()->NewExpressionStatement(
3200 assignment, RelocInfo::kNoPosition);
3201 body_block->AddStatement(variable_statement, zone());
3202 body_block->AddStatement(assignment_statement, zone());
3203 body_block->AddStatement(body, zone());
3204 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3205 scope_ = saved_scope;
3206 for_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003207 for_scope = for_scope->FinalizeBlockScope();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003208 body_block->set_scope(for_scope);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003209 // Parsed for-in loop w/ let declaration.
3210 return loop;
3211
3212 } else {
3213 init = variable_statement;
3214 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003215 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003216 Scanner::Location lhs_location = scanner()->peek_location();
Steve Blocka7e24c12009-10-30 11:49:00 +00003217 Expression* expression = ParseExpression(false, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003218 ForEachStatement::VisitMode mode;
3219 bool accept_OF = expression->AsVariableProxy();
3220
3221 if (CheckInOrOf(accept_OF, &mode)) {
3222 expression = this->CheckAndRewriteReferenceExpression(
3223 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
3224
3225 ForEachStatement* loop =
3226 factory()->NewForEachStatement(mode, labels, pos);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003227 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00003228
Steve Blocka7e24c12009-10-30 11:49:00 +00003229 Expression* enumerable = ParseExpression(true, CHECK_OK);
3230 Expect(Token::RPAREN, CHECK_OK);
3231
3232 Statement* body = ParseStatement(NULL, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003233 InitializeForEachStatement(loop, expression, enumerable, body);
3234 scope_ = saved_scope;
3235 for_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003236 for_scope = for_scope->FinalizeBlockScope();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003237 DCHECK(for_scope == NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00003238 // Parsed for-in loop.
3239 return loop;
3240
3241 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003242 init = factory()->NewExpressionStatement(
3243 expression, RelocInfo::kNoPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00003244 }
3245 }
3246 }
3247
3248 // Standard 'for' loop
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003249 ForStatement* loop = factory()->NewForStatement(labels, pos);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003250 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00003251
3252 // Parsed initializer at this point.
3253 Expect(Token::SEMICOLON, CHECK_OK);
3254
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003255 // If there are let bindings, then condition and the next statement of the
3256 // for loop must be parsed in a new scope.
3257 Scope* inner_scope = NULL;
3258 if (let_bindings.length() > 0) {
3259 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3260 inner_scope->set_start_position(scanner()->location().beg_pos);
3261 scope_ = inner_scope;
3262 }
3263
Steve Blocka7e24c12009-10-30 11:49:00 +00003264 Expression* cond = NULL;
3265 if (peek() != Token::SEMICOLON) {
3266 cond = ParseExpression(true, CHECK_OK);
3267 }
3268 Expect(Token::SEMICOLON, CHECK_OK);
3269
3270 Statement* next = NULL;
3271 if (peek() != Token::RPAREN) {
3272 Expression* exp = ParseExpression(true, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003273 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00003274 }
3275 Expect(Token::RPAREN, CHECK_OK);
3276
3277 Statement* body = ParseStatement(NULL, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003278
3279 Statement* result = NULL;
3280 if (let_bindings.length() > 0) {
3281 scope_ = for_scope;
3282 result = DesugarLetBindingsInForStatement(inner_scope, &let_bindings, loop,
3283 init, cond, next, body, CHECK_OK);
3284 scope_ = saved_scope;
3285 for_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003286 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003287 scope_ = saved_scope;
3288 for_scope->set_end_position(scanner()->location().end_pos);
3289 for_scope = for_scope->FinalizeBlockScope();
3290 if (for_scope) {
3291 // Rewrite a for statement of the form
3292 // for (const x = i; c; n) b
3293 //
3294 // into
3295 //
3296 // {
3297 // const x = i;
3298 // for (; c; n) b
3299 // }
3300 DCHECK(init != NULL);
3301 Block* block =
3302 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3303 block->AddStatement(init, zone());
3304 block->AddStatement(loop, zone());
3305 block->set_scope(for_scope);
3306 loop->Initialize(NULL, cond, next, body);
3307 result = block;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003308 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003309 loop->Initialize(init, cond, next, body);
3310 result = loop;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003311 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003312 }
3313 return result;
3314}
3315
3316
Steve Blocka7e24c12009-10-30 11:49:00 +00003317DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3318 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3319 // contexts this is used as a statement which invokes the debugger as i a
3320 // break point is present.
3321 // DebuggerStatement ::
3322 // 'debugger' ';'
3323
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003324 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00003325 Expect(Token::DEBUGGER, CHECK_OK);
3326 ExpectSemicolon(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003327 return factory()->NewDebuggerStatement(pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00003328}
3329
3330
3331bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003332 if (expression->IsLiteral()) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003333 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3334 return lit != NULL && lit->is_simple();
3335}
3336
Iain Merrick75681382010-08-19 15:07:18 +01003337
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003338Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3339 Expression* expression) {
3340 Factory* factory = isolate->factory();
3341 DCHECK(IsCompileTimeValue(expression));
3342 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003343 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3344 if (object_literal != NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003345 DCHECK(object_literal->is_simple());
Steve Block6ded16b2010-05-10 14:33:55 +01003346 if (object_literal->fast_elements()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003347 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
Steve Block6ded16b2010-05-10 14:33:55 +01003348 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003349 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
Steve Block6ded16b2010-05-10 14:33:55 +01003350 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003351 result->set(kElementsSlot, *object_literal->constant_properties());
3352 } else {
3353 ArrayLiteral* array_literal = expression->AsArrayLiteral();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003354 DCHECK(array_literal != NULL && array_literal->is_simple());
3355 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
Leon Clarkee46be812010-01-19 14:06:41 +00003356 result->set(kElementsSlot, *array_literal->constant_elements());
Steve Blocka7e24c12009-10-30 11:49:00 +00003357 }
3358 return result;
3359}
3360
3361
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003362CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3363 Handle<FixedArray> value) {
3364 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3365 return static_cast<LiteralType>(literal_type->value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003366}
3367
3368
3369Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3370 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3371}
3372
3373
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003374bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression,
3375 Scope* scope, int* num_params,
3376 Scanner::Location* dupe_loc) {
3377 // Case for empty parameter lists:
3378 // () => ...
3379 if (expression == NULL) return true;
3380
3381 // Too many parentheses around expression:
3382 // (( ... )) => ...
3383 if (expression->parenthesization_level() > 1) return false;
3384
3385 // Case for a single parameter:
3386 // (foo) => ...
3387 // foo => ...
3388 if (expression->IsVariableProxy()) {
3389 if (expression->AsVariableProxy()->is_this()) return false;
3390
3391 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name();
3392 if (traits->IsEvalOrArguments(raw_name) ||
3393 traits->IsFutureStrictReserved(raw_name))
3394 return false;
3395
3396 if (scope->IsDeclared(raw_name)) {
3397 *dupe_loc = Scanner::Location(
3398 expression->position(), expression->position() + raw_name->length());
3399 return false;
3400 }
3401
3402 scope->DeclareParameter(raw_name, VAR);
3403 ++(*num_params);
3404 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003405 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003406
3407 // Case for more than one parameter:
3408 // (foo, bar [, ...]) => ...
3409 if (expression->IsBinaryOperation()) {
3410 BinaryOperation* binop = expression->AsBinaryOperation();
3411 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() ||
3412 binop->right()->is_parenthesized())
3413 return false;
3414
3415 return CheckAndDeclareArrowParameter(traits, binop->left(), scope,
3416 num_params, dupe_loc) &&
3417 CheckAndDeclareArrowParameter(traits, binop->right(), scope,
3418 num_params, dupe_loc);
Steve Blocka7e24c12009-10-30 11:49:00 +00003419 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003420
3421 // Any other kind of expression is not a valid parameter list.
3422 return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003423}
3424
Steve Block1e0659c2011-05-24 12:43:12 +01003425
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003426int ParserTraits::DeclareArrowParametersFromExpression(
3427 Expression* expression, Scope* scope, Scanner::Location* dupe_loc,
Steve Block1e0659c2011-05-24 12:43:12 +01003428 bool* ok) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003429 int num_params = 0;
3430 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params,
3431 dupe_loc);
3432 return num_params;
Steve Block1e0659c2011-05-24 12:43:12 +01003433}
3434
Steve Blocka7e24c12009-10-30 11:49:00 +00003435
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003436FunctionLiteral* Parser::ParseFunctionLiteral(
3437 const AstRawString* function_name, Scanner::Location function_name_location,
3438 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
3439 FunctionLiteral::FunctionType function_type,
3440 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003441 // Function ::
3442 // '(' FormalParameterList? ')' '{' FunctionBody '}'
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003443 //
3444 // Getter ::
3445 // '(' ')' '{' FunctionBody '}'
3446 //
3447 // Setter ::
3448 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
3449
3450 int pos = function_token_pos == RelocInfo::kNoPosition
3451 ? peek_position() : function_token_pos;
3452
3453 bool is_generator = IsGeneratorFunction(kind);
Steve Blocka7e24c12009-10-30 11:49:00 +00003454
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003455 // Anonymous functions were passed either the empty symbol or a null
3456 // handle as the function name. Remember if we were passed a non-empty
3457 // handle to decide whether to invoke function name inference.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003458 bool should_infer_name = function_name == NULL;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003459
3460 // We want a non-null handle as the function name.
3461 if (should_infer_name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003462 function_name = ast_value_factory()->empty_string();
Steve Blocka7e24c12009-10-30 11:49:00 +00003463 }
3464
3465 int num_parameters = 0;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003466 // Function declarations are function scoped in normal mode, so they are
3467 // hoisted. In harmony block scoping mode they are block scoped, so they
3468 // are not hoisted.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003469 //
3470 // One tricky case are function declarations in a local sloppy-mode eval:
3471 // their declaration is hoisted, but they still see the local scope. E.g.,
3472 //
3473 // function() {
3474 // var x = 0
3475 // try { throw 1 } catch (x) { eval("function g() { return x }") }
3476 // return g()
3477 // }
3478 //
3479 // needs to return 1. To distinguish such cases, we need to detect
3480 // (1) whether a function stems from a sloppy eval, and
3481 // (2) whether it actually hoists across the eval.
3482 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
3483 // either information available directly, especially not when lazily compiling
3484 // a function like 'g'. We hence rely on the following invariants:
3485 // - (1) is the case iff the innermost scope of the deserialized scope chain
3486 // under which we compile is _not_ a declaration scope. This holds because
3487 // in all normal cases, function declarations are fully hoisted to a
3488 // declaration scope and compiled relative to that.
3489 // - (2) is the case iff the current declaration scope is still the original
3490 // one relative to the deserialized scope chain. Otherwise we must be
3491 // compiling a function in an inner declaration scope in the eval, e.g. a
3492 // nested function, and hoisting works normally relative to that.
3493 Scope* declaration_scope = scope_->DeclarationScope();
3494 Scope* original_declaration_scope = original_scope_->DeclarationScope();
3495 Scope* scope =
3496 function_type == FunctionLiteral::DECLARATION &&
3497 (!allow_harmony_scoping() || strict_mode() == SLOPPY) &&
3498 (original_scope_ == original_declaration_scope ||
3499 declaration_scope != original_declaration_scope)
3500 ? NewScope(declaration_scope, FUNCTION_SCOPE)
3501 : NewScope(scope_, FUNCTION_SCOPE);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003502 ZoneList<Statement*>* body = NULL;
3503 int materialized_literal_count = -1;
3504 int expected_property_count = -1;
3505 int handler_count = 0;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003506 FunctionLiteral::ParameterFlag duplicate_parameters =
3507 FunctionLiteral::kNoDuplicateParameters;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003508 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
3509 ? FunctionLiteral::kIsParenthesized
3510 : FunctionLiteral::kNotParenthesized;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003511 AstProperties ast_properties;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003512 BailoutReason dont_optimize_reason = kNoReason;
Steve Blocka7e24c12009-10-30 11:49:00 +00003513 // Parse function body.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003514 {
3515 FunctionState function_state(&function_state_, &scope_, scope, zone(),
3516 ast_value_factory(),
3517 info()->ast_node_id_gen());
3518 scope_->SetScopeName(function_name);
3519
3520 if (is_generator) {
3521 // For generators, allocating variables in contexts is currently a win
3522 // because it minimizes the work needed to suspend and resume an
3523 // activation.
3524 scope_->ForceContextAllocation();
3525
3526 // Calling a generator returns a generator object. That object is stored
3527 // in a temporary variable, a definition that is used by "yield"
3528 // expressions. This also marks the FunctionState as a generator.
3529 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3530 ast_value_factory()->dot_generator_object_string());
3531 function_state.set_generator_object_variable(temp);
3532 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003533
3534 // FormalParameterList ::
3535 // '(' (Identifier)*[','] ')'
3536 Expect(Token::LPAREN, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003537 scope->set_start_position(scanner()->location().beg_pos);
3538
3539 // We don't yet know if the function will be strict, so we cannot yet
3540 // produce errors for parameter names or duplicates. However, we remember
3541 // the locations of these errors if they occur and produce the errors later.
3542 Scanner::Location eval_args_error_log = Scanner::Location::invalid();
3543 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
Ben Murdoch257744e2011-11-30 15:57:28 +00003544 Scanner::Location reserved_loc = Scanner::Location::invalid();
Steve Block1e0659c2011-05-24 12:43:12 +01003545
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003546 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
3547 (peek() == Token::RPAREN &&
3548 arity_restriction != FunctionLiteral::SETTER_ARITY);
Steve Blocka7e24c12009-10-30 11:49:00 +00003549 while (!done) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003550 bool is_strict_reserved = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003551 const AstRawString* param_name =
3552 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01003553
3554 // Store locations for possible future error reports.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003555 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) {
3556 eval_args_error_log = scanner()->location();
Steve Block1e0659c2011-05-24 12:43:12 +01003557 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003558 if (!reserved_loc.IsValid() && is_strict_reserved) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003559 reserved_loc = scanner()->location();
3560 }
3561 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
3562 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3563 dupe_error_loc = scanner()->location();
Steve Block1e0659c2011-05-24 12:43:12 +01003564 }
3565
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003566 Variable* var = scope_->DeclareParameter(param_name, VAR);
3567 if (scope->strict_mode() == SLOPPY) {
3568 // TODO(sigurds) Mark every parameter as maybe assigned. This is a
3569 // conservative approximation necessary to account for parameters
3570 // that are assigned via the arguments array.
3571 var->set_maybe_assigned();
3572 }
3573
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003574 num_parameters++;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003575 if (num_parameters > Code::kMaxArguments) {
3576 ReportMessage("too_many_parameters");
Steve Block1e0659c2011-05-24 12:43:12 +01003577 *ok = false;
3578 return NULL;
3579 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003580 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
Steve Blocka7e24c12009-10-30 11:49:00 +00003581 done = (peek() == Token::RPAREN);
3582 if (!done) Expect(Token::COMMA, CHECK_OK);
3583 }
3584 Expect(Token::RPAREN, CHECK_OK);
3585
3586 Expect(Token::LBRACE, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00003587
3588 // If we have a named function expression, we add a local variable
3589 // declaration to the body of the function with the name of the
3590 // function and let it refer to the function itself (closure).
3591 // NOTE: We create a proxy and resolve it here so that in the
3592 // future we can change the AST to only refer to VariableProxies
3593 // instead of Variables and Proxis as is the case now.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003594 Variable* fvar = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003595 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
3596 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
3597 if (allow_harmony_scoping() && strict_mode() == STRICT) {
3598 fvar_init_op = Token::INIT_CONST;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003599 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003600 VariableMode fvar_mode =
3601 allow_harmony_scoping() && strict_mode() == STRICT
3602 ? CONST : CONST_LEGACY;
3603 DCHECK(function_name != NULL);
3604 fvar = new (zone())
3605 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */,
3606 Variable::NORMAL, kCreatedInitialized, kNotAssigned,
3607 Interface::NewConst());
3608 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
3609 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
3610 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
3611 scope_->DeclareFunctionVar(fvar_declaration);
Steve Blocka7e24c12009-10-30 11:49:00 +00003612 }
3613
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003614 // Determine if the function can be parsed lazily. Lazy parsing is different
3615 // from lazy compilation; we need to parse more eagerly than we compile.
3616
3617 // We can only parse lazily if we also compile lazily. The heuristics for
3618 // lazy compilation are:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003619 // - It must not have been prohibited by the caller to Parse (some callers
3620 // need a full AST).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003621 // - The outer scope must allow lazy compilation of inner functions.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003622 // - The function mustn't be a function expression with an open parenthesis
3623 // before; we consider that a hint that the function will be called
3624 // immediately, and it would be a waste of time to make it lazily
3625 // compiled.
3626 // These are all things we can know at this point, without looking at the
3627 // function itself.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003628
3629 // In addition, we need to distinguish between these cases:
3630 // (function foo() {
3631 // bar = function() { return 1; }
3632 // })();
3633 // and
3634 // (function foo() {
3635 // var a = 1;
3636 // bar = function() { return a; }
3637 // })();
3638
3639 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
3640 // parenthesis before the function means that it will be called
3641 // immediately). The inner function *must* be parsed eagerly to resolve the
3642 // possible reference to the variable in foo's scope. However, it's possible
3643 // that it will be compiled lazily.
3644
3645 // To make this additional case work, both Parser and PreParser implement a
3646 // logic where only top-level functions will be parsed lazily.
3647 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
3648 scope_->AllowsLazyCompilation() &&
3649 !parenthesized_function_);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003650 parenthesized_function_ = false; // The bit was set for this function only.
Steve Blocka7e24c12009-10-30 11:49:00 +00003651
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003652 if (is_lazily_parsed) {
3653 SkipLazyFunctionBody(function_name, &materialized_literal_count,
3654 &expected_property_count, CHECK_OK);
3655 } else {
3656 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
3657 is_generator, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003658 materialized_literal_count = function_state.materialized_literal_count();
3659 expected_property_count = function_state.expected_property_count();
3660 handler_count = function_state.handler_count();
Steve Blocka7e24c12009-10-30 11:49:00 +00003661 }
3662
Steve Block1e0659c2011-05-24 12:43:12 +01003663 // Validate strict mode.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003664 // Concise methods use StrictFormalParameters.
3665 if (strict_mode() == STRICT || IsConciseMethod(kind)) {
3666 CheckStrictFunctionNameAndParameters(function_name,
3667 name_is_strict_reserved,
3668 function_name_location,
3669 eval_args_error_log,
3670 dupe_error_loc,
3671 reserved_loc,
3672 CHECK_OK);
3673 }
3674 if (strict_mode() == STRICT) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003675 CheckOctalLiteral(scope->start_position(),
3676 scope->end_position(),
3677 CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01003678 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003679 ast_properties = *factory()->visitor()->ast_properties();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003680 dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
3681
3682 if (allow_harmony_scoping() && strict_mode() == STRICT) {
3683 CheckConflictingVarDeclarations(scope, CHECK_OK);
3684 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003685 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01003686
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003687 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
3688 function_name, ast_value_factory(), scope, body,
3689 materialized_literal_count, expected_property_count, handler_count,
3690 num_parameters, duplicate_parameters, function_type,
3691 FunctionLiteral::kIsFunction, parenthesized, kind, pos);
3692 function_literal->set_function_token_position(function_token_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003693 function_literal->set_ast_properties(&ast_properties);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003694 function_literal->set_dont_optimize_reason(dont_optimize_reason);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003695
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003696 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003697 return function_literal;
Steve Blocka7e24c12009-10-30 11:49:00 +00003698}
3699
3700
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003701void Parser::SkipLazyFunctionBody(const AstRawString* function_name,
3702 int* materialized_literal_count,
3703 int* expected_property_count,
3704 bool* ok) {
3705 int function_block_pos = position();
3706 if (compile_options() == ScriptCompiler::kConsumeParserCache) {
3707 // If we have cached data, we use it to skip parsing the function body. The
3708 // data contains the information we need to construct the lazy function.
3709 FunctionEntry entry =
3710 cached_parse_data_->GetFunctionEntry(function_block_pos);
3711 // Check that cached data is valid.
3712 CHECK(entry.is_valid());
3713 // End position greater than end of stream is safe, and hard to check.
3714 CHECK(entry.end_pos() > function_block_pos);
3715 scanner()->SeekForward(entry.end_pos() - 1);
3716
3717 scope_->set_end_position(entry.end_pos());
3718 Expect(Token::RBRACE, ok);
3719 if (!*ok) {
3720 return;
3721 }
3722 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3723 *materialized_literal_count = entry.literal_count();
3724 *expected_property_count = entry.property_count();
3725 scope_->SetStrictMode(entry.strict_mode());
3726 } else {
3727 // With no cached data, we partially parse the function, without building an
3728 // AST. This gathers the data needed to build a lazy function.
3729 SingletonLogger logger;
3730 PreParser::PreParseResult result =
3731 ParseLazyFunctionBodyWithPreParser(&logger);
3732 if (result == PreParser::kPreParseStackOverflow) {
3733 // Propagate stack overflow.
3734 set_stack_overflow();
3735 *ok = false;
3736 return;
3737 }
3738 if (logger.has_error()) {
3739 ParserTraits::ReportMessageAt(
3740 Scanner::Location(logger.start(), logger.end()),
3741 logger.message(), logger.argument_opt(), logger.is_reference_error());
3742 *ok = false;
3743 return;
3744 }
3745 scope_->set_end_position(logger.end());
3746 Expect(Token::RBRACE, ok);
3747 if (!*ok) {
3748 return;
3749 }
3750 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3751 *materialized_literal_count = logger.literals();
3752 *expected_property_count = logger.properties();
3753 scope_->SetStrictMode(logger.strict_mode());
3754 if (compile_options() == ScriptCompiler::kProduceParserCache) {
3755 DCHECK(log_);
3756 // Position right after terminal '}'.
3757 int body_end = scanner()->location().end_pos;
3758 log_->LogFunction(function_block_pos, body_end,
3759 *materialized_literal_count,
3760 *expected_property_count,
3761 scope_->strict_mode());
3762 }
3763 }
3764}
3765
3766
3767ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3768 const AstRawString* function_name, int pos, Variable* fvar,
3769 Token::Value fvar_init_op, bool is_generator, bool* ok) {
3770 // Everything inside an eagerly parsed function will be parsed eagerly
3771 // (see comment above).
3772 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
3773 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone());
3774 if (fvar != NULL) {
3775 VariableProxy* fproxy = scope_->NewUnresolved(
3776 factory(), function_name, Interface::NewConst());
3777 fproxy->BindTo(fvar);
3778 body->Add(factory()->NewExpressionStatement(
3779 factory()->NewAssignment(fvar_init_op,
3780 fproxy,
3781 factory()->NewThisFunction(pos),
3782 RelocInfo::kNoPosition),
3783 RelocInfo::kNoPosition), zone());
3784 }
3785
3786 // For generators, allocate and yield an iterator on function entry.
3787 if (is_generator) {
3788 ZoneList<Expression*>* arguments =
3789 new(zone()) ZoneList<Expression*>(0, zone());
3790 CallRuntime* allocation = factory()->NewCallRuntime(
3791 ast_value_factory()->empty_string(),
3792 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), arguments,
3793 pos);
3794 VariableProxy* init_proxy = factory()->NewVariableProxy(
3795 function_state_->generator_object_variable());
3796 Assignment* assignment = factory()->NewAssignment(
3797 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
3798 VariableProxy* get_proxy = factory()->NewVariableProxy(
3799 function_state_->generator_object_variable());
3800 Yield* yield = factory()->NewYield(
3801 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
3802 body->Add(factory()->NewExpressionStatement(
3803 yield, RelocInfo::kNoPosition), zone());
3804 }
3805
3806 ParseSourceElements(body, Token::RBRACE, false, false, NULL, CHECK_OK);
3807
3808 if (is_generator) {
3809 VariableProxy* get_proxy = factory()->NewVariableProxy(
3810 function_state_->generator_object_variable());
3811 Expression* undefined =
3812 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
3813 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
3814 RelocInfo::kNoPosition);
3815 body->Add(factory()->NewExpressionStatement(
3816 yield, RelocInfo::kNoPosition), zone());
3817 }
3818
3819 Expect(Token::RBRACE, CHECK_OK);
3820 scope_->set_end_position(scanner()->location().end_pos);
3821
3822 return body;
3823}
3824
3825
3826PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003827 SingletonLogger* logger) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003828 // This function may be called on a background thread too; record only the
3829 // main thread preparse times.
3830 if (pre_parse_timer_ != NULL) {
3831 pre_parse_timer_->Start();
3832 }
3833 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003834
3835 if (reusable_preparser_ == NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003836 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_);
3837 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
3838 reusable_preparser_->set_allow_modules(allow_modules());
3839 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
3840 reusable_preparser_->set_allow_lazy(true);
3841 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions());
3842 reusable_preparser_->set_allow_harmony_numeric_literals(
3843 allow_harmony_numeric_literals());
3844 reusable_preparser_->set_allow_classes(allow_classes());
3845 reusable_preparser_->set_allow_harmony_object_literals(
3846 allow_harmony_object_literals());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003847 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003848 PreParser::PreParseResult result =
3849 reusable_preparser_->PreParseLazyFunction(strict_mode(),
3850 is_generator(),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003851 logger);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003852 if (pre_parse_timer_ != NULL) {
3853 pre_parse_timer_->Stop();
3854 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003855 return result;
3856}
3857
3858
Steve Blocka7e24c12009-10-30 11:49:00 +00003859Expression* Parser::ParseV8Intrinsic(bool* ok) {
3860 // CallRuntime ::
3861 // '%' Identifier Arguments
3862
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003863 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00003864 Expect(Token::MOD, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003865 // Allow "eval" or "arguments" for backward compatibility.
3866 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00003867 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01003868
3869 if (extension_ != NULL) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003870 // The extension structures are only accessible while parsing the
3871 // very first time not when reparsing because of lazy compilation.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003872 scope_->DeclarationScope()->ForceEagerCompilation();
Steve Blocka7e24c12009-10-30 11:49:00 +00003873 }
3874
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003875 const Runtime::Function* function = Runtime::FunctionForName(name->string());
Steve Blocka7e24c12009-10-30 11:49:00 +00003876
Kristian Monsen0d5e1162010-09-30 15:31:59 +01003877 // Check for built-in IS_VAR macro.
3878 if (function != NULL &&
3879 function->intrinsic_type == Runtime::RUNTIME &&
3880 function->function_id == Runtime::kIS_VAR) {
3881 // %IS_VAR(x) evaluates to x if x is a variable,
3882 // leads to a parse error otherwise. Could be implemented as an
3883 // inline function %_IS_VAR(x) to eliminate this special case.
3884 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
3885 return args->at(0);
3886 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003887 ReportMessage("not_isvar");
Steve Block6ded16b2010-05-10 14:33:55 +01003888 *ok = false;
3889 return NULL;
Steve Block6ded16b2010-05-10 14:33:55 +01003890 }
3891 }
3892
Kristian Monsen0d5e1162010-09-30 15:31:59 +01003893 // Check that the expected number of arguments are being passed.
3894 if (function != NULL &&
3895 function->nargs != -1 &&
3896 function->nargs != args->length()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003897 ReportMessage("illegal_access");
3898 *ok = false;
3899 return NULL;
3900 }
3901
3902 // Check that the function is defined if it's an inline runtime call.
3903 if (function == NULL && name->FirstCharacter() == '_') {
3904 ParserTraits::ReportMessage("not_defined", name);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01003905 *ok = false;
3906 return NULL;
3907 }
3908
3909 // We have a valid intrinsics call or a call to a builtin.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003910 return factory()->NewCallRuntime(name, function, args, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00003911}
3912
3913
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003914Literal* Parser::GetLiteralUndefined(int position) {
3915 return factory()->NewUndefinedLiteral(position);
Steve Block1e0659c2011-05-24 12:43:12 +01003916}
3917
3918
Ben Murdoch589d6972011-11-30 16:04:58 +00003919void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
3920 Declaration* decl = scope->CheckConflictingVarDeclarations();
3921 if (decl != NULL) {
3922 // In harmony mode we treat conflicting variable bindinds as early
3923 // errors. See ES5 16 for a definition of early errors.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003924 const AstRawString* name = decl->proxy()->raw_name();
Ben Murdoch589d6972011-11-30 16:04:58 +00003925 int position = decl->proxy()->position();
3926 Scanner::Location location = position == RelocInfo::kNoPosition
3927 ? Scanner::Location::invalid()
3928 : Scanner::Location(position, position + 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003929 ParserTraits::ReportMessageAt(location, "var_redeclaration", name);
Ben Murdoch589d6972011-11-30 16:04:58 +00003930 *ok = false;
3931 }
3932}
3933
3934
Steve Blocka7e24c12009-10-30 11:49:00 +00003935// ----------------------------------------------------------------------------
3936// Parser support
3937
3938
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003939bool Parser::TargetStackContainsLabel(const AstRawString* label) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003940 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3941 BreakableStatement* stat = t->node()->AsBreakableStatement();
3942 if (stat != NULL && ContainsLabel(stat->labels(), label))
3943 return true;
3944 }
3945 return false;
3946}
3947
3948
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003949BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
3950 bool* ok) {
3951 bool anonymous = label == NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00003952 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3953 BreakableStatement* stat = t->node()->AsBreakableStatement();
3954 if (stat == NULL) continue;
3955 if ((anonymous && stat->is_target_for_anonymous()) ||
3956 (!anonymous && ContainsLabel(stat->labels(), label))) {
3957 RegisterTargetUse(stat->break_target(), t->previous());
3958 return stat;
3959 }
3960 }
3961 return NULL;
3962}
3963
3964
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003965IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
Steve Blocka7e24c12009-10-30 11:49:00 +00003966 bool* ok) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003967 bool anonymous = label == NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00003968 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3969 IterationStatement* stat = t->node()->AsIterationStatement();
3970 if (stat == NULL) continue;
3971
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003972 DCHECK(stat->is_target_for_anonymous());
Steve Blocka7e24c12009-10-30 11:49:00 +00003973 if (anonymous || ContainsLabel(stat->labels(), label)) {
3974 RegisterTargetUse(stat->continue_target(), t->previous());
3975 return stat;
3976 }
3977 }
3978 return NULL;
3979}
3980
3981
Ben Murdoch8b112d22011-06-08 16:22:53 +01003982void Parser::RegisterTargetUse(Label* target, Target* stop) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003983 // Register that a break target found at the given stop in the
3984 // target stack has been used from the top of the target stack. Add
3985 // the break target to any TargetCollectors passed on the stack.
3986 for (Target* t = target_stack_; t != stop; t = t->previous()) {
3987 TargetCollector* collector = t->node()->AsTargetCollector();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003988 if (collector != NULL) collector->AddTarget(target, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00003989 }
3990}
3991
3992
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003993void Parser::HandleSourceURLComments() {
3994 if (scanner_.source_url()->length() > 0) {
3995 Handle<String> source_url = scanner_.source_url()->Internalize(isolate());
3996 info_->script()->set_source_url(*source_url);
3997 }
3998 if (scanner_.source_mapping_url()->length() > 0) {
3999 Handle<String> source_mapping_url =
4000 scanner_.source_mapping_url()->Internalize(isolate());
4001 info_->script()->set_source_mapping_url(*source_mapping_url);
4002 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004003}
4004
4005
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004006void Parser::ThrowPendingError() {
4007 DCHECK(ast_value_factory()->IsInternalized());
4008 if (has_pending_error_) {
4009 MessageLocation location(script(), pending_error_location_.beg_pos,
4010 pending_error_location_.end_pos);
4011 Factory* factory = isolate()->factory();
4012 bool has_arg =
4013 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL;
4014 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0);
4015 if (pending_error_arg_ != NULL) {
4016 Handle<String> arg_string = pending_error_arg_->string();
4017 elements->set(0, *arg_string);
4018 } else if (pending_error_char_arg_ != NULL) {
4019 Handle<String> arg_string =
4020 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_))
4021 .ToHandleChecked();
4022 elements->set(0, *arg_string);
4023 }
4024 isolate()->debug()->OnCompileError(script());
4025
4026 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
4027 Handle<Object> error;
4028 MaybeHandle<Object> maybe_error =
4029 pending_error_is_reference_error_
4030 ? factory->NewReferenceError(pending_error_message_, array)
4031 : factory->NewSyntaxError(pending_error_message_, array);
4032 if (maybe_error.ToHandle(&error)) isolate()->Throw(*error, &location);
4033 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004034}
4035
4036
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004037void Parser::Internalize() {
4038 // Internalize strings.
4039 ast_value_factory()->Internalize(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00004040
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004041 // Error processing.
4042 if (info()->function() == NULL) {
4043 if (stack_overflow()) {
4044 isolate()->StackOverflow();
4045 } else {
4046 ThrowPendingError();
Steve Blocka7e24c12009-10-30 11:49:00 +00004047 }
4048 }
Steve Block1e0659c2011-05-24 12:43:12 +01004049
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004050 // Move statistics to Isolate.
4051 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
4052 ++feature) {
4053 for (int i = 0; i < use_counts_[feature]; ++i) {
4054 isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature));
4055 }
4056 }
4057 isolate()->counters()->total_preparse_skipped()->Increment(
4058 total_preparse_skipped_);
Steve Blocka7e24c12009-10-30 11:49:00 +00004059}
4060
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004061
Leon Clarke4515c472010-02-03 11:58:03 +00004062// ----------------------------------------------------------------------------
Steve Blocka7e24c12009-10-30 11:49:00 +00004063// Regular expressions
4064
4065
4066RegExpParser::RegExpParser(FlatStringReader* in,
4067 Handle<String>* error,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004068 bool multiline,
4069 Zone* zone)
4070 : isolate_(zone->isolate()),
4071 zone_(zone),
Steve Block44f0eee2011-05-26 01:26:41 +01004072 error_(error),
4073 captures_(NULL),
4074 in_(in),
4075 current_(kEndMarker),
4076 next_pos_(0),
4077 capture_count_(0),
4078 has_more_(true),
4079 multiline_(multiline),
4080 simple_(false),
4081 contains_anchor_(false),
4082 is_scanned_for_captures_(false),
4083 failed_(false) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01004084 Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +00004085}
4086
4087
4088uc32 RegExpParser::Next() {
4089 if (has_next()) {
4090 return in()->Get(next_pos_);
4091 } else {
4092 return kEndMarker;
4093 }
4094}
4095
4096
4097void RegExpParser::Advance() {
4098 if (next_pos_ < in()->length()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004099 StackLimitCheck check(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00004100 if (check.HasOverflowed()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004101 ReportError(CStrVector(Isolate::kStackOverflowMessage));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004102 } else if (zone()->excess_allocation()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004103 ReportError(CStrVector("Regular expression too large"));
4104 } else {
4105 current_ = in()->Get(next_pos_);
4106 next_pos_++;
4107 }
4108 } else {
4109 current_ = kEndMarker;
4110 has_more_ = false;
4111 }
4112}
4113
4114
4115void RegExpParser::Reset(int pos) {
4116 next_pos_ = pos;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004117 has_more_ = (pos < in()->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00004118 Advance();
4119}
4120
4121
4122void RegExpParser::Advance(int dist) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01004123 next_pos_ += dist - 1;
4124 Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +00004125}
4126
4127
4128bool RegExpParser::simple() {
4129 return simple_;
4130}
4131
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004132
Steve Blocka7e24c12009-10-30 11:49:00 +00004133RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
4134 failed_ = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004135 *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00004136 // Zip to the end to make sure the no more input is read.
4137 current_ = kEndMarker;
4138 next_pos_ = in()->length();
4139 return NULL;
4140}
4141
4142
4143// Pattern ::
4144// Disjunction
4145RegExpTree* RegExpParser::ParsePattern() {
4146 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004147 DCHECK(!has_more());
Steve Blocka7e24c12009-10-30 11:49:00 +00004148 // If the result of parsing is a literal string atom, and it has the
4149 // same length as the input, then the atom is identical to the input.
4150 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
4151 simple_ = true;
4152 }
4153 return result;
4154}
4155
4156
4157// Disjunction ::
4158// Alternative
4159// Alternative | Disjunction
4160// Alternative ::
4161// [empty]
4162// Term Alternative
4163// Term ::
4164// Assertion
4165// Atom
4166// Atom Quantifier
4167RegExpTree* RegExpParser::ParseDisjunction() {
4168 // Used to store current state while parsing subexpressions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004169 RegExpParserState initial_state(NULL, INITIAL, 0, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004170 RegExpParserState* stored_state = &initial_state;
4171 // Cache the builder in a local variable for quick access.
4172 RegExpBuilder* builder = initial_state.builder();
4173 while (true) {
4174 switch (current()) {
4175 case kEndMarker:
4176 if (stored_state->IsSubexpression()) {
4177 // Inside a parenthesized group when hitting end of input.
4178 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
4179 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004180 DCHECK_EQ(INITIAL, stored_state->group_type());
Steve Blocka7e24c12009-10-30 11:49:00 +00004181 // Parsing completed successfully.
4182 return builder->ToRegExp();
4183 case ')': {
4184 if (!stored_state->IsSubexpression()) {
4185 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
4186 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004187 DCHECK_NE(INITIAL, stored_state->group_type());
Steve Blocka7e24c12009-10-30 11:49:00 +00004188
4189 Advance();
4190 // End disjunction parsing and convert builder content to new single
4191 // regexp atom.
4192 RegExpTree* body = builder->ToRegExp();
4193
4194 int end_capture_index = captures_started();
4195
4196 int capture_index = stored_state->capture_index();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004197 SubexpressionType group_type = stored_state->group_type();
Steve Blocka7e24c12009-10-30 11:49:00 +00004198
4199 // Restore previous state.
4200 stored_state = stored_state->previous_state();
4201 builder = stored_state->builder();
4202
4203 // Build result of subexpression.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004204 if (group_type == CAPTURE) {
Ben Murdoch8b112d22011-06-08 16:22:53 +01004205 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00004206 captures_->at(capture_index - 1) = capture;
4207 body = capture;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004208 } else if (group_type != GROUPING) {
4209 DCHECK(group_type == POSITIVE_LOOKAHEAD ||
4210 group_type == NEGATIVE_LOOKAHEAD);
4211 bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004212 body = new(zone()) RegExpLookahead(body,
Steve Blocka7e24c12009-10-30 11:49:00 +00004213 is_positive,
4214 end_capture_index - capture_index,
4215 capture_index);
4216 }
4217 builder->AddAtom(body);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01004218 // For compatability with JSC and ES3, we allow quantifiers after
4219 // lookaheads, and break in all cases.
Steve Blocka7e24c12009-10-30 11:49:00 +00004220 break;
4221 }
4222 case '|': {
4223 Advance();
4224 builder->NewAlternative();
4225 continue;
4226 }
4227 case '*':
4228 case '+':
4229 case '?':
4230 return ReportError(CStrVector("Nothing to repeat"));
4231 case '^': {
4232 Advance();
4233 if (multiline_) {
4234 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004235 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
Steve Blocka7e24c12009-10-30 11:49:00 +00004236 } else {
4237 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004238 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
Steve Blocka7e24c12009-10-30 11:49:00 +00004239 set_contains_anchor();
4240 }
4241 continue;
4242 }
4243 case '$': {
4244 Advance();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004245 RegExpAssertion::AssertionType assertion_type =
Steve Blocka7e24c12009-10-30 11:49:00 +00004246 multiline_ ? RegExpAssertion::END_OF_LINE :
4247 RegExpAssertion::END_OF_INPUT;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004248 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
Steve Blocka7e24c12009-10-30 11:49:00 +00004249 continue;
4250 }
4251 case '.': {
4252 Advance();
4253 // everything except \x0a, \x0d, \u2028 and \u2029
Ben Murdoch257744e2011-11-30 15:57:28 +00004254 ZoneList<CharacterRange>* ranges =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004255 new(zone()) ZoneList<CharacterRange>(2, zone());
4256 CharacterRange::AddClassEscape('.', ranges, zone());
Ben Murdoch8b112d22011-06-08 16:22:53 +01004257 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004258 builder->AddAtom(atom);
4259 break;
4260 }
4261 case '(': {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004262 SubexpressionType subexpr_type = CAPTURE;
Steve Blocka7e24c12009-10-30 11:49:00 +00004263 Advance();
4264 if (current() == '?') {
4265 switch (Next()) {
4266 case ':':
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004267 subexpr_type = GROUPING;
Steve Blocka7e24c12009-10-30 11:49:00 +00004268 break;
4269 case '=':
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004270 subexpr_type = POSITIVE_LOOKAHEAD;
Steve Blocka7e24c12009-10-30 11:49:00 +00004271 break;
4272 case '!':
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004273 subexpr_type = NEGATIVE_LOOKAHEAD;
Steve Blocka7e24c12009-10-30 11:49:00 +00004274 break;
4275 default:
4276 ReportError(CStrVector("Invalid group") CHECK_FAILED);
4277 break;
4278 }
4279 Advance(2);
4280 } else {
4281 if (captures_ == NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004282 captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004283 }
4284 if (captures_started() >= kMaxCaptures) {
4285 ReportError(CStrVector("Too many captures") CHECK_FAILED);
4286 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004287 captures_->Add(NULL, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004288 }
4289 // Store current state and begin new disjunction parsing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004290 stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
4291 captures_started(), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004292 builder = stored_state->builder();
Ben Murdoche0cee9b2011-05-25 10:26:03 +01004293 continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00004294 }
4295 case '[': {
4296 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
4297 builder->AddAtom(atom);
4298 break;
4299 }
4300 // Atom ::
4301 // \ AtomEscape
4302 case '\\':
4303 switch (Next()) {
4304 case kEndMarker:
4305 return ReportError(CStrVector("\\ at end of pattern"));
4306 case 'b':
4307 Advance(2);
4308 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004309 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
Steve Blocka7e24c12009-10-30 11:49:00 +00004310 continue;
4311 case 'B':
4312 Advance(2);
4313 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004314 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
Steve Blocka7e24c12009-10-30 11:49:00 +00004315 continue;
Ben Murdoche0cee9b2011-05-25 10:26:03 +01004316 // AtomEscape ::
4317 // CharacterClassEscape
4318 //
4319 // CharacterClassEscape :: one of
4320 // d D s S w W
Steve Blocka7e24c12009-10-30 11:49:00 +00004321 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
4322 uc32 c = Next();
4323 Advance(2);
Ben Murdoch257744e2011-11-30 15:57:28 +00004324 ZoneList<CharacterRange>* ranges =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004325 new(zone()) ZoneList<CharacterRange>(2, zone());
4326 CharacterRange::AddClassEscape(c, ranges, zone());
Ben Murdoch8b112d22011-06-08 16:22:53 +01004327 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004328 builder->AddAtom(atom);
4329 break;
4330 }
4331 case '1': case '2': case '3': case '4': case '5': case '6':
4332 case '7': case '8': case '9': {
4333 int index = 0;
4334 if (ParseBackReferenceIndex(&index)) {
4335 RegExpCapture* capture = NULL;
4336 if (captures_ != NULL && index <= captures_->length()) {
4337 capture = captures_->at(index - 1);
4338 }
4339 if (capture == NULL) {
4340 builder->AddEmpty();
4341 break;
4342 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01004343 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
Steve Blocka7e24c12009-10-30 11:49:00 +00004344 builder->AddAtom(atom);
4345 break;
4346 }
4347 uc32 first_digit = Next();
4348 if (first_digit == '8' || first_digit == '9') {
4349 // Treat as identity escape
4350 builder->AddCharacter(first_digit);
4351 Advance(2);
4352 break;
4353 }
4354 }
4355 // FALLTHROUGH
4356 case '0': {
4357 Advance();
4358 uc32 octal = ParseOctalLiteral();
4359 builder->AddCharacter(octal);
4360 break;
4361 }
4362 // ControlEscape :: one of
4363 // f n r t v
4364 case 'f':
4365 Advance(2);
4366 builder->AddCharacter('\f');
4367 break;
4368 case 'n':
4369 Advance(2);
4370 builder->AddCharacter('\n');
4371 break;
4372 case 'r':
4373 Advance(2);
4374 builder->AddCharacter('\r');
4375 break;
4376 case 't':
4377 Advance(2);
4378 builder->AddCharacter('\t');
4379 break;
4380 case 'v':
4381 Advance(2);
4382 builder->AddCharacter('\v');
4383 break;
4384 case 'c': {
Ben Murdoch086aeea2011-05-13 15:57:08 +01004385 Advance();
4386 uc32 controlLetter = Next();
4387 // Special case if it is an ASCII letter.
4388 // Convert lower case letters to uppercase.
4389 uc32 letter = controlLetter & ~('a' ^ 'A');
4390 if (letter < 'A' || 'Z' < letter) {
4391 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4392 // This is outside the specification. We match JSC in
4393 // reading the backslash as a literal character instead
4394 // of as starting an escape.
4395 builder->AddCharacter('\\');
4396 } else {
4397 Advance(2);
4398 builder->AddCharacter(controlLetter & 0x1f);
4399 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004400 break;
4401 }
4402 case 'x': {
4403 Advance(2);
4404 uc32 value;
4405 if (ParseHexEscape(2, &value)) {
4406 builder->AddCharacter(value);
4407 } else {
4408 builder->AddCharacter('x');
4409 }
4410 break;
4411 }
4412 case 'u': {
4413 Advance(2);
4414 uc32 value;
4415 if (ParseHexEscape(4, &value)) {
4416 builder->AddCharacter(value);
4417 } else {
4418 builder->AddCharacter('u');
4419 }
4420 break;
4421 }
4422 default:
4423 // Identity escape.
4424 builder->AddCharacter(Next());
4425 Advance(2);
4426 break;
4427 }
4428 break;
4429 case '{': {
4430 int dummy;
4431 if (ParseIntervalQuantifier(&dummy, &dummy)) {
4432 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
4433 }
4434 // fallthrough
4435 }
4436 default:
4437 builder->AddCharacter(current());
4438 Advance();
4439 break;
4440 } // end switch(current())
4441
4442 int min;
4443 int max;
4444 switch (current()) {
4445 // QuantifierPrefix ::
4446 // *
4447 // +
4448 // ?
4449 // {
4450 case '*':
4451 min = 0;
4452 max = RegExpTree::kInfinity;
4453 Advance();
4454 break;
4455 case '+':
4456 min = 1;
4457 max = RegExpTree::kInfinity;
4458 Advance();
4459 break;
4460 case '?':
4461 min = 0;
4462 max = 1;
4463 Advance();
4464 break;
4465 case '{':
4466 if (ParseIntervalQuantifier(&min, &max)) {
4467 if (max < min) {
4468 ReportError(CStrVector("numbers out of order in {} quantifier.")
4469 CHECK_FAILED);
4470 }
4471 break;
4472 } else {
4473 continue;
4474 }
4475 default:
4476 continue;
4477 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004478 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
Steve Blocka7e24c12009-10-30 11:49:00 +00004479 if (current() == '?') {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004480 quantifier_type = RegExpQuantifier::NON_GREEDY;
Leon Clarkee46be812010-01-19 14:06:41 +00004481 Advance();
4482 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
4483 // FLAG_regexp_possessive_quantifier is a debug-only flag.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004484 quantifier_type = RegExpQuantifier::POSSESSIVE;
Steve Blocka7e24c12009-10-30 11:49:00 +00004485 Advance();
4486 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004487 builder->AddQuantifierToAtom(min, max, quantifier_type);
Steve Blocka7e24c12009-10-30 11:49:00 +00004488 }
4489}
4490
Steve Blocka7e24c12009-10-30 11:49:00 +00004491
4492#ifdef DEBUG
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004493// Currently only used in an DCHECK.
Steve Blocka7e24c12009-10-30 11:49:00 +00004494static bool IsSpecialClassEscape(uc32 c) {
4495 switch (c) {
4496 case 'd': case 'D':
4497 case 's': case 'S':
4498 case 'w': case 'W':
4499 return true;
4500 default:
4501 return false;
4502 }
4503}
4504#endif
4505
4506
4507// In order to know whether an escape is a backreference or not we have to scan
4508// the entire regexp and find the number of capturing parentheses. However we
4509// don't want to scan the regexp twice unless it is necessary. This mini-parser
4510// is called when needed. It can see the difference between capturing and
4511// noncapturing parentheses and can skip character classes and backslash-escaped
4512// characters.
4513void RegExpParser::ScanForCaptures() {
4514 // Start with captures started previous to current position
4515 int capture_count = captures_started();
4516 // Add count of captures after this position.
4517 int n;
4518 while ((n = current()) != kEndMarker) {
4519 Advance();
4520 switch (n) {
4521 case '\\':
4522 Advance();
4523 break;
4524 case '[': {
4525 int c;
4526 while ((c = current()) != kEndMarker) {
4527 Advance();
4528 if (c == '\\') {
4529 Advance();
4530 } else {
4531 if (c == ']') break;
4532 }
4533 }
4534 break;
4535 }
4536 case '(':
4537 if (current() != '?') capture_count++;
4538 break;
4539 }
4540 }
4541 capture_count_ = capture_count;
4542 is_scanned_for_captures_ = true;
4543}
4544
4545
4546bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004547 DCHECK_EQ('\\', current());
4548 DCHECK('1' <= Next() && Next() <= '9');
Steve Blocka7e24c12009-10-30 11:49:00 +00004549 // Try to parse a decimal literal that is no greater than the total number
4550 // of left capturing parentheses in the input.
4551 int start = position();
4552 int value = Next() - '0';
4553 Advance(2);
4554 while (true) {
4555 uc32 c = current();
4556 if (IsDecimalDigit(c)) {
4557 value = 10 * value + (c - '0');
4558 if (value > kMaxCaptures) {
4559 Reset(start);
4560 return false;
4561 }
4562 Advance();
4563 } else {
4564 break;
4565 }
4566 }
4567 if (value > captures_started()) {
4568 if (!is_scanned_for_captures_) {
4569 int saved_position = position();
4570 ScanForCaptures();
4571 Reset(saved_position);
4572 }
4573 if (value > capture_count_) {
4574 Reset(start);
4575 return false;
4576 }
4577 }
4578 *index_out = value;
4579 return true;
4580}
4581
4582
4583// QuantifierPrefix ::
4584// { DecimalDigits }
4585// { DecimalDigits , }
4586// { DecimalDigits , DecimalDigits }
4587//
4588// Returns true if parsing succeeds, and set the min_out and max_out
4589// values. Values are truncated to RegExpTree::kInfinity if they overflow.
4590bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004591 DCHECK_EQ(current(), '{');
Steve Blocka7e24c12009-10-30 11:49:00 +00004592 int start = position();
4593 Advance();
4594 int min = 0;
4595 if (!IsDecimalDigit(current())) {
4596 Reset(start);
4597 return false;
4598 }
4599 while (IsDecimalDigit(current())) {
4600 int next = current() - '0';
4601 if (min > (RegExpTree::kInfinity - next) / 10) {
4602 // Overflow. Skip past remaining decimal digits and return -1.
4603 do {
4604 Advance();
4605 } while (IsDecimalDigit(current()));
4606 min = RegExpTree::kInfinity;
4607 break;
4608 }
4609 min = 10 * min + next;
4610 Advance();
4611 }
4612 int max = 0;
4613 if (current() == '}') {
4614 max = min;
4615 Advance();
4616 } else if (current() == ',') {
4617 Advance();
4618 if (current() == '}') {
4619 max = RegExpTree::kInfinity;
4620 Advance();
4621 } else {
4622 while (IsDecimalDigit(current())) {
4623 int next = current() - '0';
4624 if (max > (RegExpTree::kInfinity - next) / 10) {
4625 do {
4626 Advance();
4627 } while (IsDecimalDigit(current()));
4628 max = RegExpTree::kInfinity;
4629 break;
4630 }
4631 max = 10 * max + next;
4632 Advance();
4633 }
4634 if (current() != '}') {
4635 Reset(start);
4636 return false;
4637 }
4638 Advance();
4639 }
4640 } else {
4641 Reset(start);
4642 return false;
4643 }
4644 *min_out = min;
4645 *max_out = max;
4646 return true;
4647}
4648
4649
Steve Blocka7e24c12009-10-30 11:49:00 +00004650uc32 RegExpParser::ParseOctalLiteral() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004651 DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker);
Steve Blocka7e24c12009-10-30 11:49:00 +00004652 // For compatibility with some other browsers (not all), we parse
4653 // up to three octal digits with a value below 256.
4654 uc32 value = current() - '0';
4655 Advance();
4656 if ('0' <= current() && current() <= '7') {
4657 value = value * 8 + current() - '0';
4658 Advance();
4659 if (value < 32 && '0' <= current() && current() <= '7') {
4660 value = value * 8 + current() - '0';
4661 Advance();
4662 }
4663 }
4664 return value;
4665}
4666
4667
4668bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
4669 int start = position();
4670 uc32 val = 0;
4671 bool done = false;
4672 for (int i = 0; !done; i++) {
4673 uc32 c = current();
4674 int d = HexValue(c);
4675 if (d < 0) {
4676 Reset(start);
4677 return false;
4678 }
4679 val = val * 16 + d;
4680 Advance();
4681 if (i == length - 1) {
4682 done = true;
4683 }
4684 }
4685 *value = val;
4686 return true;
4687}
4688
4689
4690uc32 RegExpParser::ParseClassCharacterEscape() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004691 DCHECK(current() == '\\');
4692 DCHECK(has_next() && !IsSpecialClassEscape(Next()));
Steve Blocka7e24c12009-10-30 11:49:00 +00004693 Advance();
4694 switch (current()) {
4695 case 'b':
4696 Advance();
4697 return '\b';
4698 // ControlEscape :: one of
4699 // f n r t v
4700 case 'f':
4701 Advance();
4702 return '\f';
4703 case 'n':
4704 Advance();
4705 return '\n';
4706 case 'r':
4707 Advance();
4708 return '\r';
4709 case 't':
4710 Advance();
4711 return '\t';
4712 case 'v':
4713 Advance();
4714 return '\v';
Ben Murdoch086aeea2011-05-13 15:57:08 +01004715 case 'c': {
4716 uc32 controlLetter = Next();
4717 uc32 letter = controlLetter & ~('A' ^ 'a');
4718 // For compatibility with JSC, inside a character class
4719 // we also accept digits and underscore as control characters.
4720 if ((controlLetter >= '0' && controlLetter <= '9') ||
4721 controlLetter == '_' ||
4722 (letter >= 'A' && letter <= 'Z')) {
4723 Advance(2);
4724 // Control letters mapped to ASCII control characters in the range
4725 // 0x00-0x1f.
4726 return controlLetter & 0x1f;
4727 }
4728 // We match JSC in reading the backslash as a literal
4729 // character instead of as starting an escape.
4730 return '\\';
4731 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004732 case '0': case '1': case '2': case '3': case '4': case '5':
4733 case '6': case '7':
4734 // For compatibility, we interpret a decimal escape that isn't
4735 // a back reference (and therefore either \0 or not valid according
4736 // to the specification) as a 1..3 digit octal character code.
4737 return ParseOctalLiteral();
4738 case 'x': {
4739 Advance();
4740 uc32 value;
4741 if (ParseHexEscape(2, &value)) {
4742 return value;
4743 }
4744 // If \x is not followed by a two-digit hexadecimal, treat it
4745 // as an identity escape.
4746 return 'x';
4747 }
4748 case 'u': {
4749 Advance();
4750 uc32 value;
4751 if (ParseHexEscape(4, &value)) {
4752 return value;
4753 }
4754 // If \u is not followed by a four-digit hexadecimal, treat it
4755 // as an identity escape.
4756 return 'u';
4757 }
4758 default: {
4759 // Extended identity escape. We accept any character that hasn't
4760 // been matched by a more specific case, not just the subset required
4761 // by the ECMAScript specification.
4762 uc32 result = current();
4763 Advance();
4764 return result;
4765 }
4766 }
4767 return 0;
4768}
4769
4770
4771CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004772 DCHECK_EQ(0, *char_class);
Steve Blocka7e24c12009-10-30 11:49:00 +00004773 uc32 first = current();
4774 if (first == '\\') {
4775 switch (Next()) {
4776 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
4777 *char_class = Next();
4778 Advance(2);
4779 return CharacterRange::Singleton(0); // Return dummy value.
4780 }
4781 case kEndMarker:
4782 return ReportError(CStrVector("\\ at end of pattern"));
4783 default:
4784 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
4785 return CharacterRange::Singleton(c);
4786 }
4787 } else {
4788 Advance();
4789 return CharacterRange::Singleton(first);
4790 }
4791}
4792
4793
Ben Murdochb0fe1622011-05-05 13:52:32 +01004794static const uc16 kNoCharClass = 0;
4795
4796// Adds range or pre-defined character class to character ranges.
4797// If char_class is not kInvalidClass, it's interpreted as a class
4798// escape (i.e., 's' means whitespace, from '\s').
4799static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
4800 uc16 char_class,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004801 CharacterRange range,
4802 Zone* zone) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01004803 if (char_class != kNoCharClass) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004804 CharacterRange::AddClassEscape(char_class, ranges, zone);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004805 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004806 ranges->Add(range, zone);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004807 }
4808}
4809
4810
Steve Blocka7e24c12009-10-30 11:49:00 +00004811RegExpTree* RegExpParser::ParseCharacterClass() {
4812 static const char* kUnterminated = "Unterminated character class";
4813 static const char* kRangeOutOfOrder = "Range out of order in character class";
4814
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004815 DCHECK_EQ(current(), '[');
Steve Blocka7e24c12009-10-30 11:49:00 +00004816 Advance();
4817 bool is_negated = false;
4818 if (current() == '^') {
4819 is_negated = true;
4820 Advance();
4821 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004822 ZoneList<CharacterRange>* ranges =
4823 new(zone()) ZoneList<CharacterRange>(2, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004824 while (has_more() && current() != ']') {
Ben Murdochb0fe1622011-05-05 13:52:32 +01004825 uc16 char_class = kNoCharClass;
Steve Blocka7e24c12009-10-30 11:49:00 +00004826 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
Steve Blocka7e24c12009-10-30 11:49:00 +00004827 if (current() == '-') {
4828 Advance();
4829 if (current() == kEndMarker) {
4830 // If we reach the end we break out of the loop and let the
4831 // following code report an error.
4832 break;
4833 } else if (current() == ']') {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004834 AddRangeOrEscape(ranges, char_class, first, zone());
4835 ranges->Add(CharacterRange::Singleton('-'), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004836 break;
4837 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01004838 uc16 char_class_2 = kNoCharClass;
4839 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
4840 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
4841 // Either end is an escaped character class. Treat the '-' verbatim.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004842 AddRangeOrEscape(ranges, char_class, first, zone());
4843 ranges->Add(CharacterRange::Singleton('-'), zone());
4844 AddRangeOrEscape(ranges, char_class_2, next, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004845 continue;
4846 }
4847 if (first.from() > next.to()) {
4848 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
4849 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004850 ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004851 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004852 AddRangeOrEscape(ranges, char_class, first, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004853 }
4854 }
4855 if (!has_more()) {
4856 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
4857 }
4858 Advance();
4859 if (ranges->length() == 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004860 ranges->Add(CharacterRange::Everything(), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004861 is_negated = !is_negated;
4862 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01004863 return new(zone()) RegExpCharacterClass(ranges, is_negated);
Steve Blocka7e24c12009-10-30 11:49:00 +00004864}
4865
4866
4867// ----------------------------------------------------------------------------
4868// The Parser interface.
4869
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08004870bool RegExpParser::ParseRegExp(FlatStringReader* input,
4871 bool multiline,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004872 RegExpCompileData* result,
4873 Zone* zone) {
4874 DCHECK(result != NULL);
4875 RegExpParser parser(input, &result->error, multiline, zone);
Steve Blocka7e24c12009-10-30 11:49:00 +00004876 RegExpTree* tree = parser.ParsePattern();
4877 if (parser.failed()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004878 DCHECK(tree == NULL);
4879 DCHECK(!result->error.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00004880 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004881 DCHECK(tree != NULL);
4882 DCHECK(result->error.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00004883 result->tree = tree;
4884 int capture_count = parser.captures_started();
4885 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
4886 result->contains_anchor = parser.contains_anchor();
4887 result->capture_count = capture_count;
4888 }
4889 return !parser.failed();
4890}
4891
4892
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004893bool Parser::Parse() {
4894 DCHECK(info()->function() == NULL);
Ben Murdochf87a2032010-10-22 12:50:53 +01004895 FunctionLiteral* result = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004896 pre_parse_timer_ = isolate()->counters()->pre_parse();
4897 if (FLAG_trace_parse || allow_natives_syntax() || extension_ != NULL) {
4898 // If intrinsics are allowed, the Parser cannot operate independent of the
4899 // V8 heap because of Runtime. Tell the string table to internalize strings
4900 // and values right after they're created.
4901 ast_value_factory()->Internalize(isolate());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004902 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004903
4904 if (info()->is_lazy()) {
4905 DCHECK(!info()->is_eval());
4906 if (info()->shared_info()->is_function()) {
4907 result = ParseLazy();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004908 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004909 result = ParseProgram();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004910 }
Leon Clarke4515c472010-02-03 11:58:03 +00004911 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004912 SetCachedData();
4913 result = ParseProgram();
Leon Clarke4515c472010-02-03 11:58:03 +00004914 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004915 info()->SetFunction(result);
4916
4917 Internalize();
4918 DCHECK(ast_value_factory()->IsInternalized());
Ben Murdochf87a2032010-10-22 12:50:53 +01004919 return (result != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00004920}
4921
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004922
4923void Parser::ParseOnBackground() {
4924 DCHECK(info()->function() == NULL);
4925 FunctionLiteral* result = NULL;
4926 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
4927
4928 CompleteParserRecorder recorder;
4929 if (compile_options() == ScriptCompiler::kProduceParserCache) {
4930 log_ = &recorder;
4931 }
4932
4933 DCHECK(info()->source_stream() != NULL);
4934 ExternalStreamingStream stream(info()->source_stream(),
4935 info()->source_stream_encoding());
4936 scanner_.Initialize(&stream);
4937 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext());
4938
4939 // When streaming, we don't know the length of the source until we have parsed
4940 // it. The raw data can be UTF-8, so we wouldn't know the source length until
4941 // we have decoded it anyway even if we knew the raw data length (which we
4942 // don't). We work around this by storing all the scopes which need their end
4943 // position set at the end of the script (the top scope and possible eval
4944 // scopes) and set their end position after we know the script length.
4945 Scope* top_scope = NULL;
4946 Scope* eval_scope = NULL;
4947 result = DoParseProgram(info(), &top_scope, &eval_scope);
4948
4949 top_scope->set_end_position(scanner()->location().end_pos);
4950 if (eval_scope != NULL) {
4951 eval_scope->set_end_position(scanner()->location().end_pos);
4952 }
4953
4954 info()->SetFunction(result);
4955
4956 // We cannot internalize on a background thread; a foreground task will take
4957 // care of calling Parser::Internalize just before compilation.
4958
4959 if (compile_options() == ScriptCompiler::kProduceParserCache) {
4960 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
4961 log_ = NULL;
4962 }
4963}
Steve Blocka7e24c12009-10-30 11:49:00 +00004964} } // namespace v8::internal