1fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/api.h" 8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/ast.h" 9b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org#include "src/bailout-reason.h" 105de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/platform.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/char-predicates-inl.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compiler.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/messages.h" 16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/parser.h" 17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/preparser.h" 18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime.h" 19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scanner-character-streams.h" 20196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopeinfo.h" 21196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/string-stream.h" 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 2471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.orgRegExpBuilder::RegExpBuilder(Zone* zone) 27400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org : zone_(zone), 28c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org pending_empty_(false), 29c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org characters_(NULL), 30c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org terms_(), 31c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org alternatives_() 32a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifdef DEBUG 33c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org , last_added_(ADD_NONE) 34a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif 35a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org {} 36a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 37a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 38a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushCharacters() { 39a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org pending_empty_ = false; 40a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (characters_ != NULL) { 41c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector()); 42a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org characters_ = NULL; 437028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org text_.Add(atom, zone()); 44a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_ATOM); 45a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 46a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 47a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 48a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 49a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushText() { 50a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushCharacters(); 51a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int num_text = text_.length(); 52a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (num_text == 0) { 53a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 54a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (num_text == 1) { 557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org terms_.Add(text_.last(), zone()); 56a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org RegExpText* text = new(zone()) RegExpText(zone()); 58a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org for (int i = 0; i < num_text; i++) 597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org text_.Get(i)->AppendToText(text, zone()); 607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org terms_.Add(text, zone()); 61a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 62a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org text_.Clear(); 63a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 64a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 65a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 66a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddCharacter(uc16 c) { 67a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org pending_empty_ = false; 68a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (characters_ == NULL) { 697028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org characters_ = new(zone()) ZoneList<uc16>(4, zone()); 70a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org characters_->Add(c, zone()); 72a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_CHAR); 73a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 74a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 75a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 76a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddEmpty() { 77a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org pending_empty_ = true; 78a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 79a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 80a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 81a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddAtom(RegExpTree* term) { 82a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (term->IsEmpty()) { 83a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org AddEmpty(); 84a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 85a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 86a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (term->IsTextElement()) { 87a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushCharacters(); 887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org text_.Add(term, zone()); 89a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 90a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushText(); 917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org terms_.Add(term, zone()); 92a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 93a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_ATOM); 94a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 95a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 96a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 97a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddAssertion(RegExpTree* assert) { 98a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushText(); 997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org terms_.Add(assert, zone()); 100a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_ASSERT); 101a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 102a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 103a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 104a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::NewAlternative() { 105a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushTerms(); 106a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 107a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 108a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 109a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushTerms() { 110a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushText(); 111a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int num_terms = terms_.length(); 112a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpTree* alternative; 113a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (num_terms == 0) { 114a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org alternative = RegExpEmpty::GetInstance(); 115a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (num_terms == 1) { 116a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org alternative = terms_.last(); 117a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 1187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org alternative = new(zone()) RegExpAlternative(terms_.GetList(zone())); 119a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 1207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org alternatives_.Add(alternative, zone()); 121a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org terms_.Clear(); 122a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_NONE); 123a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 124a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 125a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 126a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpBuilder::ToRegExp() { 127a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushTerms(); 128a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int num_alternatives = alternatives_.length(); 129a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (num_alternatives == 0) { 130a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return RegExpEmpty::GetInstance(); 131a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 132a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (num_alternatives == 1) { 133a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return alternatives_.last(); 134a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 1357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org return new(zone()) RegExpDisjunction(alternatives_.GetList(zone())); 136a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 137a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 138a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 139dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgvoid RegExpBuilder::AddQuantifierToAtom( 140dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org int min, int max, RegExpQuantifier::QuantifierType quantifier_type) { 141a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (pending_empty_) { 142a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org pending_empty_ = false; 143a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 144a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 145a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpTree* atom; 146a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (characters_ != NULL) { 147e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(last_added_ == ADD_CHAR); 148a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Last atom was character. 149a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Vector<const uc16> char_vector = characters_->ToConstVector(); 150a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int num_chars = char_vector.length(); 151a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (num_chars > 1) { 152a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1); 1537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org text_.Add(new(zone()) RegExpAtom(prefix), zone()); 154a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org char_vector = char_vector.SubVector(num_chars - 1, num_chars); 155a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 156a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org characters_ = NULL; 157c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org atom = new(zone()) RegExpAtom(char_vector); 158a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushText(); 159a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (text_.length() > 0) { 160e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(last_added_ == ADD_ATOM); 161a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org atom = text_.RemoveLast(); 162a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushText(); 163a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (terms_.length() > 0) { 164e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(last_added_ == ADD_ATOM); 165a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org atom = terms_.RemoveLast(); 16637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (atom->max_match() == 0) { 16737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Guaranteed to only match an empty string. 168a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_TERM); 169a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (min == 0) { 170a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 171a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 1727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org terms_.Add(atom, zone()); 173a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 174a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 175a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 176a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Only call immediately after adding an atom or character! 177a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org UNREACHABLE(); 178a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 179a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 180dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org terms_.Add( 181dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); 182a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_TERM); 183a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 184a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 185a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 18670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgFunctionEntry ParseData::GetFunctionEntry(int start) { 187d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // The current pre-data entry must be a FunctionEntry with the given 188d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // start position. 18970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if ((function_index_ + FunctionEntry::kSize <= Length()) && 19070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org (static_cast<int>(Data()[function_index_]) == start)) { 1915b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org int index = function_index_; 1925b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org function_index_ += FunctionEntry::kSize; 19370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize); 19470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return FunctionEntry(subvector); 19543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 19643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return FunctionEntry(); 19743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 19843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgint ParseData::FunctionCount() { 20170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org int functions_size = FunctionsSize(); 20270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (functions_size < 0) return 0; 20370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (functions_size % FunctionEntry::kSize != 0) return 0; 20470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return functions_size / FunctionEntry::kSize; 2055b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org} 2065b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 2075b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 20870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgbool ParseData::IsSane() { 2095b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org // Check that the header data is valid and doesn't specify 2105b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org // point to positions outside the store. 21170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org int data_length = Length(); 21270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (data_length < PreparseDataConstants::kHeaderSize) return false; 21370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (Magic() != PreparseDataConstants::kMagicNumber) return false; 21470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (Version() != PreparseDataConstants::kCurrentVersion) return false; 21570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (HasError()) return false; 2165b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org // Check that the space allocated for function entries is sane. 21770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org int functions_size = FunctionsSize(); 2185b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org if (functions_size < 0) return false; 2195b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org if (functions_size % FunctionEntry::kSize != 0) return false; 220d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Check that the total size has room for header and function entries. 2215b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org int minimum_size = 222beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org PreparseDataConstants::kHeaderSize + functions_size; 22370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (data_length < minimum_size) return false; 22443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 22543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 22643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgvoid ParseData::Initialize() { 22970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // Prepares state for use. 23070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org int data_length = Length(); 23170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (data_length >= PreparseDataConstants::kHeaderSize) { 23270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org function_index_ = PreparseDataConstants::kHeaderSize; 23365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 23443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 23543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgbool ParseData::HasError() { 23870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return Data()[PreparseDataConstants::kHasErrorOffset]; 239ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org} 240ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 241ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 24270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgunsigned ParseData::Magic() { 24370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return Data()[PreparseDataConstants::kMagicOffset]; 24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 24543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgunsigned ParseData::Version() { 24870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return Data()[PreparseDataConstants::kVersionOffset]; 24943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgint ParseData::FunctionsSize() { 25370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]); 25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgvoid Parser::SetCachedData() { 2584c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (compile_options() == ScriptCompiler::kNoCompileOptions) { 25970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org cached_parse_data_ = NULL; 26070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } else { 261e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info_->cached_data() != NULL); 2624c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (compile_options() == ScriptCompiler::kConsumeParserCache) { 26370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org cached_parse_data_ = new ParseData(*info_->cached_data()); 26470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 26570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 269dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgScope* Parser::NewScope(Scope* parent, ScopeType scope_type) { 2706313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org DCHECK(ast_value_factory()); 27108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Scope* result = 2726313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org new (zone()) Scope(parent, scope_type, ast_value_factory(), zone()); 273394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com result->Initialize(); 27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 27943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Target is a support class to facilitate manipulation of the 28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Parser's target_stack_ (the stack of potential 'break' and 28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 'continue' statement targets). Upon construction, a new target is 28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// added; it is removed upon destruction. 28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Target BASE_EMBEDDED { 28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 286e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target(Target** variable, AstNode* node) 287e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org : variable_(variable), node_(node), previous_(*variable) { 288e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org *variable = this; 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ~Target() { 292e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org *variable_ = previous_; 29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 295b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Target* previous() { return previous_; } 2960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org AstNode* node() { return node_; } 297b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 299e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target** variable_; 3000b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org AstNode* node_; 301b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Target* previous_; 30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass TargetScope BASE_EMBEDDED { 30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 307e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org explicit TargetScope(Target** variable) 308e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org : variable_(variable), previous_(*variable) { 309e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org *variable = NULL; 31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ~TargetScope() { 313e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org *variable_ = previous_; 31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 317e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target** variable_; 318b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Target* previous_; 31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The CHECK_OK macro is a convenient macro to enforce error 32443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// handling for functions that may fail (by returning !*ok). 32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 32643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// CAUTION: This macro appends extra statements after a call, 32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// thus it must never be used where only a single statement 32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// is correct (e.g. an if statement branch w/o braces)! 32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define CHECK_OK ok); \ 33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!*ok) return NULL; \ 33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ((void)0 33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DUMMY ) // to make indentation work 33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DUMMY 33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 336a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#define CHECK_FAILED /**/); \ 337a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (failed_) return NULL; \ 338a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ((void)0 339a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#define DUMMY ) // to make indentation work 340a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#undef DUMMY 34143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 34343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of Parser 34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 345f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.orgclass ParserTraits::Checkpoint 346f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org : public ParserBase<ParserTraits>::CheckpointBase { 347f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org public: 348f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org explicit Checkpoint(ParserBase<ParserTraits>* parser) 349a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org : CheckpointBase(parser), parser_(parser) { 350a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org saved_ast_node_id_gen_ = *parser_->ast_node_id_gen_; 351f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org } 352f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org 353f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org void Restore() { 354f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org CheckpointBase::Restore(); 355a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org *parser_->ast_node_id_gen_ = saved_ast_node_id_gen_; 356f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org } 357f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org 358f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org private: 359a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ParserBase<ParserTraits>* parser_; 360a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org AstNode::IdGen saved_ast_node_id_gen_; 361f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org}; 362f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org 363f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org 36408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgbool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { 3656313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org return identifier == parser_->ast_value_factory()->eval_string() || 3666313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org identifier == parser_->ast_value_factory()->arguments_string(); 367f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 368f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 369f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 370a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgbool ParserTraits::IsPrototype(const AstRawString* identifier) const { 371a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return identifier == parser_->ast_value_factory()->prototype_string(); 372a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org} 373a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 374a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 375a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgbool ParserTraits::IsConstructor(const AstRawString* identifier) const { 376a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return identifier == parser_->ast_value_factory()->constructor_string(); 377a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org} 378a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 379a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 3806b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgbool ParserTraits::IsThisProperty(Expression* expression) { 381e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expression != NULL); 3826b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org Property* property = expression->AsProperty(); 3836b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org return property != NULL && 3846b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org property->obj()->AsVariableProxy() != NULL && 3856b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org property->obj()->AsVariableProxy()->is_this(); 3866b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org} 3876b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 3886b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 38969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.orgbool ParserTraits::IsIdentifier(Expression* expression) { 39069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org VariableProxy* operand = expression->AsVariableProxy(); 39169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org return operand != NULL && !operand->is_this(); 39269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org} 39369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 39469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 395fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.orgvoid ParserTraits::PushPropertyName(FuncNameInferrer* fni, 396fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Expression* expression) { 397fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (expression->IsPropertyName()) { 39808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); 399fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } else { 400fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org fni->PushLiteralName( 4016313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org parser_->ast_value_factory()->anonymous_function_string()); 402fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 403fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org} 404fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 405fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 4066b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgvoid ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, 4076b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org Expression* right) { 408e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left != NULL); 4096b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org if (left->AsProperty() != NULL && 4106b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org right->AsFunctionLiteral() != NULL) { 4116b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org right->AsFunctionLiteral()->set_pretenure(); 4126b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org } 4136b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org} 4146b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 4156b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 416fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.orgvoid ParserTraits::CheckPossibleEvalCall(Expression* expression, 417fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Scope* scope) { 418fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org VariableProxy* callee = expression->AsVariableProxy(); 419fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (callee != NULL && 4206313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org callee->raw_name() == parser_->ast_value_factory()->eval_string()) { 421fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org scope->DeclarationScope()->RecordEvalCall(); 422fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 423fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org} 424fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 425fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 426248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.orgExpression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) { 427248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org VariableProxy* proxy = 428248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org expression != NULL ? expression->AsVariableProxy() : NULL; 429248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org if (proxy != NULL) proxy->set_is_assigned(); 4306b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org return expression; 4316b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org} 4326b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 4336b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 4342904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgbool ParserTraits::ShortcutNumericLiteralBinaryExpression( 4352904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Expression** x, Expression* y, Token::Value op, int pos, 4362904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org AstNodeFactory<AstConstructionVisitor>* factory) { 43708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() && 43808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) { 43908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org double x_val = (*x)->AsLiteral()->raw_value()->AsNumber(); 44008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org double y_val = y->AsLiteral()->raw_value()->AsNumber(); 4412904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org switch (op) { 4422904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org case Token::ADD: 4432904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org *x = factory->NewNumberLiteral(x_val + y_val, pos); 4442904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org return true; 4452904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org case Token::SUB: 4462904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org *x = factory->NewNumberLiteral(x_val - y_val, pos); 4472904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org return true; 4482904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org case Token::MUL: 4492904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org *x = factory->NewNumberLiteral(x_val * y_val, pos); 4502904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org return true; 4512904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org case Token::DIV: 4522904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org *x = factory->NewNumberLiteral(x_val / y_val, pos); 4532904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org return true; 4542904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org case Token::BIT_OR: { 4552904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); 4562904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org *x = factory->NewNumberLiteral(value, pos); 4572904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org return true; 4582904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 4592904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org case Token::BIT_AND: { 4602904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); 4612904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org *x = factory->NewNumberLiteral(value, pos); 4622904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org return true; 4632904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 4642904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org case Token::BIT_XOR: { 4652904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); 4662904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org *x = factory->NewNumberLiteral(value, pos); 4672904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org return true; 4682904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 4692904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org case Token::SHL: { 4702904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); 4712904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org *x = factory->NewNumberLiteral(value, pos); 4722904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org return true; 4732904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 4742904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org case Token::SHR: { 4752904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org uint32_t shift = DoubleToInt32(y_val) & 0x1f; 4762904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org uint32_t value = DoubleToUint32(x_val) >> shift; 4772904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org *x = factory->NewNumberLiteral(value, pos); 4782904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org return true; 4792904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 4802904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org case Token::SAR: { 4812904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org uint32_t shift = DoubleToInt32(y_val) & 0x1f; 4822904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); 4832904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org *x = factory->NewNumberLiteral(value, pos); 4842904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org return true; 4852904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 4862904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org default: 4872904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org break; 4882904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 4892904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 4902904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org return false; 4912904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org} 4922904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 4932904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 49469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.orgExpression* ParserTraits::BuildUnaryExpression( 49569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Expression* expression, Token::Value op, int pos, 49669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org AstNodeFactory<AstConstructionVisitor>* factory) { 497e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expression != NULL); 498196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (expression->IsLiteral()) { 49908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstValue* literal = expression->AsLiteral()->raw_value(); 50069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (op == Token::NOT) { 50169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // Convert the literal to a boolean condition and negate it. 50269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org bool condition = literal->BooleanValue(); 50308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org return factory->NewBooleanLiteral(!condition, pos); 50469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } else if (literal->IsNumber()) { 50569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // Compute some expressions involving only number literals. 50608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org double value = literal->AsNumber(); 50769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org switch (op) { 50869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org case Token::ADD: 50969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org return expression; 51069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org case Token::SUB: 51169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org return factory->NewNumberLiteral(-value, pos); 51269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org case Token::BIT_NOT: 51369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org return factory->NewNumberLiteral(~DoubleToInt32(value), pos); 51469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org default: 51569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org break; 51669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 51769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 51869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 51969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // Desugar '+foo' => 'foo*1' 52069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (op == Token::ADD) { 52169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org return factory->NewBinaryOperation( 52269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos); 52369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 52469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // The same idea for '-foo' => 'foo*(-1)'. 52569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (op == Token::SUB) { 52669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org return factory->NewBinaryOperation( 52769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos); 52869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 52969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // ...and one more time for '~foo' => 'foo^(~0)'. 53069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (op == Token::BIT_NOT) { 53169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org return factory->NewBinaryOperation( 53269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); 53369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 53469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org return factory->NewUnaryOperation(op, expression, pos); 53569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org} 53669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 53769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 5384edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.orgExpression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { 5394edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org return NewThrowError( 5406313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org parser_->ast_value_factory()->make_reference_error_string(), message, 5416313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org NULL, pos); 5424edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org} 5434edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 5444edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 5454edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.orgExpression* ParserTraits::NewThrowSyntaxError( 54608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const char* message, const AstRawString* arg, int pos) { 5476313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org return NewThrowError(parser_->ast_value_factory()->make_syntax_error_string(), 54808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org message, arg, pos); 5494edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org} 5504edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 5514edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 5524edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.orgExpression* ParserTraits::NewThrowTypeError( 55308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const char* message, const AstRawString* arg, int pos) { 5546313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org return NewThrowError(parser_->ast_value_factory()->make_type_error_string(), 55508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org message, arg, pos); 5564edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org} 5574edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 5584edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 5594edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.orgExpression* ParserTraits::NewThrowError( 56008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* constructor, const char* message, 56108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* arg, int pos) { 5624edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org Zone* zone = parser_->zone(); 56308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org int argc = arg != NULL ? 1 : 0; 56408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* type = 5656313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org parser_->ast_value_factory()->GetOneByteString(message); 56608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<const AstRawString*>* array = 56708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org new (zone) ZoneList<const AstRawString*>(argc, zone); 56808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org if (arg != NULL) { 56908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org array->Add(arg, zone); 57008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org } 57108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone); 57208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org args->Add(parser_->factory()->NewStringLiteral(type, pos), zone); 57308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org args->Add(parser_->factory()->NewStringListLiteral(array, pos), zone); 5744edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org CallRuntime* call_constructor = 5754edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); 5764edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org return parser_->factory()->NewThrow(call_constructor, pos); 5774edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org} 5784edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 5794edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 580f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid ParserTraits::ReportMessageAt(Scanner::Location source_location, 581f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const char* message, 582285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org const char* arg, 5832904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org bool is_reference_error) { 58497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org if (parser_->stack_overflow()) { 58597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org // Suppress the error message (syntax error or such) in the presence of a 58697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org // stack overflow. The isolate allows only one pending exception at at time 58797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org // and we want to report the stack overflow later. 58897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return; 58997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org } 5906a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org parser_->has_pending_error_ = true; 5916a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org parser_->pending_error_location_ = source_location; 5926a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org parser_->pending_error_message_ = message; 5936a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org parser_->pending_error_char_arg_ = arg; 59408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org parser_->pending_error_arg_ = NULL; 5956a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org parser_->pending_error_is_reference_error_ = is_reference_error; 596f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 597f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 598f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 599f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid ParserTraits::ReportMessage(const char* message, 60008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const char* arg, 60108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool is_reference_error) { 60208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Scanner::Location source_location = parser_->scanner()->location(); 60308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ReportMessageAt(source_location, message, arg, is_reference_error); 60408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org} 60508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org 60608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org 60708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgvoid ParserTraits::ReportMessage(const char* message, 60808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* arg, 6092904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org bool is_reference_error) { 610f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scanner::Location source_location = parser_->scanner()->location(); 611285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ReportMessageAt(source_location, message, arg, is_reference_error); 612f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 613f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 614f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 615f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid ParserTraits::ReportMessageAt(Scanner::Location source_location, 616f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const char* message, 61708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* arg, 6182904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org bool is_reference_error) { 61997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org if (parser_->stack_overflow()) { 62097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org // Suppress the error message (syntax error or such) in the presence of a 62197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org // stack overflow. The isolate allows only one pending exception at at time 62297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org // and we want to report the stack overflow later. 62397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return; 62497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org } 6256a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org parser_->has_pending_error_ = true; 6266a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org parser_->pending_error_location_ = source_location; 6276a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org parser_->pending_error_message_ = message; 6286a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org parser_->pending_error_char_arg_ = NULL; 6296a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org parser_->pending_error_arg_ = arg; 6306a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org parser_->pending_error_is_reference_error_ = is_reference_error; 631f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 632f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 633f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 63408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgconst AstRawString* ParserTraits::GetSymbol(Scanner* scanner) { 63508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* result = 6366313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org parser_->scanner()->CurrentSymbol(parser_->ast_value_factory()); 637e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result != NULL); 638b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org return result; 639f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 640f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 641f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 642a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgconst AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) { 643a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org double double_value = parser_->scanner()->DoubleValue(); 644a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org char array[100]; 645a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org const char* string = 646fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org DoubleToCString(double_value, Vector<char>(array, arraysize(array))); 647a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return ast_value_factory()->GetOneByteString(string); 648a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 649a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 650a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 65108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgconst AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) { 6526313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org return parser_->scanner()->NextSymbol(parser_->ast_value_factory()); 653f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 654f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 655f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 656f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgExpression* ParserTraits::ThisExpression( 6579d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) { 6589d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org return factory->NewVariableProxy(scope->receiver(), pos); 659f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 660f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 6615e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgExpression* ParserTraits::SuperReference( 6625e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) { 6635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org return factory->NewSuperReference( 6645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org ThisExpression(scope, factory, pos)->AsVariableProxy(), 6655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org pos); 6665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org} 667f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 668a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgExpression* ParserTraits::ClassLiteral( 669a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org const AstRawString* name, Expression* extends, Expression* constructor, 670a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org ZoneList<ObjectLiteral::Property*>* properties, int pos, 671a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org AstNodeFactory<AstConstructionVisitor>* factory) { 672a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return factory->NewClassLiteral(name, extends, constructor, properties, pos); 673a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org} 674a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 675486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgLiteral* ParserTraits::ExpressionFromLiteral( 676f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Token::Value token, int pos, 677f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scanner* scanner, 678f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org AstNodeFactory<AstConstructionVisitor>* factory) { 679f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org switch (token) { 680f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case Token::NULL_LITERAL: 68108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org return factory->NewNullLiteral(pos); 682f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case Token::TRUE_LITERAL: 68308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org return factory->NewBooleanLiteral(true, pos); 684f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case Token::FALSE_LITERAL: 68508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org return factory->NewBooleanLiteral(false, pos); 686f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case Token::NUMBER: { 68797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org double value = scanner->DoubleValue(); 688f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return factory->NewNumberLiteral(value, pos); 689f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 690f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org default: 691e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(false); 692f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 693f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return NULL; 694f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 695f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 696f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 697f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgExpression* ParserTraits::ExpressionFromIdentifier( 69808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name, int pos, Scope* scope, 699f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org AstNodeFactory<AstConstructionVisitor>* factory) { 700f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); 701f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // The name may refer to a module instance object, so its type is unknown. 702f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#ifdef DEBUG 703f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (FLAG_print_interface_details) 70408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org PrintF("# Variable %.*s ", name->length(), name->raw_data()); 705f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#endif 706f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Interface* interface = Interface::NewUnknown(parser_->zone()); 707f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return scope->NewUnresolved(factory, name, interface, pos); 708f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 709f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 710f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 711f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgExpression* ParserTraits::ExpressionFromString( 712f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int pos, Scanner* scanner, 713f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org AstNodeFactory<AstConstructionVisitor>* factory) { 71408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* symbol = GetSymbol(scanner); 715f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); 71608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org return factory->NewStringLiteral(symbol, pos); 717f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 718f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 7203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgExpression* ParserTraits::GetIterator( 7213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Expression* iterable, AstNodeFactory<AstConstructionVisitor>* factory) { 7223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Expression* iterator_symbol_literal = 7233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org factory->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition); 7243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org int pos = iterable->position(); 7253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Expression* prop = 7263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org factory->NewProperty(iterable, iterator_symbol_literal, pos); 7273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Zone* zone = parser_->zone(); 7283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone); 7293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org return factory->NewCall(prop, args, pos); 7303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org} 7313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 7323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 733f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgLiteral* ParserTraits::GetLiteralTheHole( 734f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int position, AstNodeFactory<AstConstructionVisitor>* factory) { 73508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org return factory->NewTheHoleLiteral(RelocInfo::kNoPosition); 736f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 737f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 738f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 739f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgExpression* ParserTraits::ParseV8Intrinsic(bool* ok) { 740f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return parser_->ParseV8Intrinsic(ok); 741f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 742f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 743f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 744486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgFunctionLiteral* ParserTraits::ParseFunctionLiteral( 7452c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org const AstRawString* name, Scanner::Location function_name_location, 7462c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org bool name_is_strict_reserved, FunctionKind kind, 7472c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org int function_token_position, FunctionLiteral::FunctionType type, 7482c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { 7492c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org return parser_->ParseFunctionLiteral( 7502c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org name, function_name_location, name_is_strict_reserved, kind, 7512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org function_token_position, type, arity_restriction, ok); 752486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org} 753486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org 754486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org 75521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.orgParser::Parser(CompilationInfo* info, ParseInfo* parse_info) 75621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org : ParserBase<ParserTraits>(&scanner_, parse_info->stack_limit, 75721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org info->extension(), NULL, info->zone(), 75821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org info->ast_node_id_gen(), this), 75921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org scanner_(parse_info->unicode_cache), 7601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org reusable_preparser_(NULL), 7611e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org original_scope_(NULL), 76243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen target_stack_(NULL), 76370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org cached_parse_data_(NULL), 7646a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org info_(info), 7656a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org has_pending_error_(false), 7666a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org pending_error_message_(NULL), 76708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org pending_error_arg_(NULL), 76821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org pending_error_char_arg_(NULL), 76921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org total_preparse_skipped_(0), 77021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org pre_parse_timer_(NULL) { 771b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org DCHECK(!script().is_null() || info->source_stream() != NULL); 772e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); 773e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_modules(!info->is_native() && FLAG_harmony_modules); 774e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); 775e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_lazy(false); // Must be explicitly enabled. 7769bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org set_allow_arrow_functions(FLAG_harmony_arrow_functions); 777ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); 7785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org set_allow_classes(FLAG_harmony_classes); 7792c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org set_allow_harmony_object_literals(FLAG_harmony_object_literals); 7805de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 7815de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org ++feature) { 7825de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org use_counts_[feature] = 0; 7835de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org } 7846313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org if (info->ast_value_factory() == NULL) { 7856313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org // info takes ownership of AstValueFactory. 7866313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org info->SetAstValueFactory( 7876313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org new AstValueFactory(zone(), parse_info->hash_seed)); 78821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org } 78943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 79043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 79143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgFunctionLiteral* Parser::ParseProgram() { 7934000f228dd279f96628ed845f1e81d01ba7e14d8jkummerow@chromium.org // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, 7944000f228dd279f96628ed845f1e81d01ba7e14d8jkummerow@chromium.org // see comment for HistogramTimerScope class. 79521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org 79621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org // It's OK to use the counters here, since this function is only called in 79721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org // the main thread. 7984000f228dd279f96628ed845f1e81d01ba7e14d8jkummerow@chromium.org HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); 7996313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Handle<String> source(String::cast(script()->source())); 8007979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org isolate()->counters()->total_parse_size()->Increment(source->length()); 8015de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::ElapsedTimer timer; 802dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (FLAG_trace_parse) { 803dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org timer.Start(); 804dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } 8056313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 80643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 80743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize parser state. 80869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org CompleteParserRecorder recorder; 8094c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 8104c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (compile_options() == ScriptCompiler::kProduceParserCache) { 81169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org log_ = &recorder; 8124c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org } else if (compile_options() == ScriptCompiler::kConsumeParserCache) { 81370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org cached_parse_data_->Initialize(); 81469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 81569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 8169e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org source = String::Flatten(source); 817304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FunctionLiteral* result; 818b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 819b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Scope* top_scope = NULL; 820b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Scope* eval_scope = NULL; 8215f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org if (source->IsExternalTwoByteString()) { 8225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Notice that the stream is destroyed at the end of the branch block. 8235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // The last line of the blocks can't be moved outside, even though they're 8245f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // identical calls. 825154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ExternalTwoByteStringUtf16CharacterStream stream( 8265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 8279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org scanner_.Initialize(&stream); 828b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org result = DoParseProgram(info(), &top_scope, &eval_scope); 8295f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else { 830154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org GenericStringUtf16CharacterStream stream(source, 0, source->length()); 8319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org scanner_.Initialize(&stream); 832b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org result = DoParseProgram(info(), &top_scope, &eval_scope); 833b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org } 834b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org top_scope->set_end_position(source->length()); 835b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org if (eval_scope != NULL) { 836b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org eval_scope->set_end_position(source->length()); 8375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 83821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org HandleSourceURLComments(); 839304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 840304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (FLAG_trace_parse && result != NULL) { 841dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org double ms = timer.Elapsed().InMillisecondsF(); 842304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (info()->is_eval()) { 843304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF("[parsing eval"); 844304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } else if (info()->script()->name()->IsString()) { 845304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org String* name = String::cast(info()->script()->name()); 846304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org SmartArrayPointer<char> name_chars = name->ToCString(); 847afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org PrintF("[parsing script: %s", name_chars.get()); 848304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } else { 849304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF("[parsing script"); 850304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 851304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF(" - took %0.3f ms]\n", ms); 852304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 8534c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (compile_options() == ScriptCompiler::kProduceParserCache) { 85470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); 85569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org log_ = NULL; 85669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 857304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org return result; 8585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 8595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 8605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 861b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgFunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, 862b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Scope** eval_scope) { 863e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(scope_ == NULL); 864e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(target_stack_ == NULL); 86543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 86643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FunctionLiteral* result = NULL; 867b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org { 868b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org *scope = NewScope(scope_, GLOBAL_SCOPE); 869b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org info->SetGlobalScope(*scope); 87012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org if (!info->context().is_null() && !info->context()->IsNativeContext()) { 871b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org *scope = Scope::DeserializeScopeChain(*info->context(), *scope, zone()); 87208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org // The Scope is backed up by ScopeInfo (which is in the V8 heap); this 87308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org // means the Parser cannot operate independent of the V8 heap. Tell the 87408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org // string table to internalize strings and values right after they're 87508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org // created. 8766313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->Internalize(isolate()); 877355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org } 878b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org original_scope_ = *scope; 8792c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (info->is_eval()) { 880b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org if (!(*scope)->is_global_scope() || info->strict_mode() == STRICT) { 881b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org *scope = NewScope(*scope, EVAL_SCOPE); 8822c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } 883355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org } else if (info->is_global()) { 884b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org *scope = NewScope(*scope, GLOBAL_SCOPE); 88527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } 886b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org (*scope)->set_start_position(0); 887b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // End position will be set by the caller. 888355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 889cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org // Compute the parsing mode. 890e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; 891b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org if (allow_natives_syntax() || extension_ != NULL || 892b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org (*scope)->is_eval_scope()) { 893cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org mode = PARSE_EAGERLY; 894cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org } 895cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org ParsingModeScope parsing_mode(this, mode); 896cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org 897f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Enters 'scope'. 898b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org FunctionState function_state(&function_state_, &scope_, *scope, zone(), 8996313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory(), info->ast_node_id_gen()); 900f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 901486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org scope_->SetStrictMode(info->strict_mode()); 9027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 90343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool ok = true; 904f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int beg_pos = scanner()->location().beg_pos; 905b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org ParseSourceElements(body, Token::EOS, info->is_eval(), true, eval_scope, 906b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org &ok); 907d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 908486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (ok && strict_mode() == STRICT) { 909f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); 9100ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 9111805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 912a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { 913f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CheckConflictingVarDeclarations(scope_, &ok); 9141805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 9151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 9169faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { 9179faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (body->length() != 1 || 9189faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org !body->at(0)->IsExpressionStatement() || 9199faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org !body->at(0)->AsExpressionStatement()-> 9209faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org expression()->IsFunctionLiteral()) { 921285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ReportMessage("single_function_literal"); 9229faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org ok = false; 9239faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 9249faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 9259faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org 92643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (ok) { 927b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewFunctionLiteral( 9286313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->empty_string(), ast_value_factory(), scope_, 9296313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org body, function_state.materialized_literal_count(), 930c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org function_state.expected_property_count(), 9319d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org function_state.handler_count(), 0, 93256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org FunctionLiteral::kNoDuplicateParameters, 9339d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, 9342c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0); 935b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result->set_ast_properties(factory()->visitor()->ast_properties()); 9362c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org result->set_dont_optimize_reason( 9372c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org factory()->visitor()->dont_optimize_reason()); 93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 93943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 94143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure the target stack is empty. 942e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(target_stack_ == NULL); 94343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 94443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 94543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 94643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 947f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 9485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgFunctionLiteral* Parser::ParseLazy() { 94921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org // It's OK to use the counters here, since this function is only called in 95021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org // the main thread. 951dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); 9526313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Handle<String> source(String::cast(script()->source())); 9537979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org isolate()->counters()->total_parse_size()->Increment(source->length()); 9545de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::ElapsedTimer timer; 955dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (FLAG_trace_parse) { 956dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org timer.Start(); 957dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } 9585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared_info = info()->shared_info(); 959304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 9605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Initialize parser state. 9619e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org source = String::Flatten(source); 962304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FunctionLiteral* result; 9635f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org if (source->IsExternalTwoByteString()) { 964154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ExternalTwoByteStringUtf16CharacterStream stream( 9655f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Handle<ExternalTwoByteString>::cast(source), 9664d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org shared_info->start_position(), 9674d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org shared_info->end_position()); 9681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org result = ParseLazy(&stream); 9695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else { 970154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org GenericStringUtf16CharacterStream stream(source, 971154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org shared_info->start_position(), 972154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org shared_info->end_position()); 9731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org result = ParseLazy(&stream); 9745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 975304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 976304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (FLAG_trace_parse && result != NULL) { 977dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org double ms = timer.Elapsed().InMillisecondsF(); 978de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); 979afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); 980304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 981304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org return result; 9825f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 9835f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 9845f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 9851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgFunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { 9865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared_info = info()->shared_info(); 9879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org scanner_.Initialize(source); 988e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(scope_ == NULL); 989e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(target_stack_ == NULL); 9905f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 9914d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org Handle<String> name(String::cast(shared_info->name())); 9926313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org DCHECK(ast_value_factory()); 9936313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 9946313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org const AstRawString* raw_name = ast_value_factory()->GetString(name); 99508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org fni_->PushEnclosingName(raw_name); 99665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 997471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 99843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 99943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Place holder for the result. 100043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FunctionLiteral* result = NULL; 100143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 100243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen { 100343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse the function literal. 1004f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* scope = NewScope(scope_, GLOBAL_SCOPE); 10055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org info()->SetGlobalScope(scope); 10065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (!info()->closure().is_null()) { 10075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, 10087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org zone()); 10094d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } 10101e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org original_scope_ = scope; 101108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org FunctionState function_state(&function_state_, &scope_, scope, zone(), 10126313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory(), 10136313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org info()->ast_node_id_gen()); 1014e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); 1015e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->strict_mode() == shared_info->strict_mode()); 1016486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org scope->SetStrictMode(shared_info->strict_mode()); 1017dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org FunctionLiteral::FunctionType function_type = shared_info->is_expression() 10187c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org ? (shared_info->is_anonymous() 10197c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org ? FunctionLiteral::ANONYMOUS_EXPRESSION 10207c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org : FunctionLiteral::NAMED_EXPRESSION) 10217c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org : FunctionLiteral::DECLARATION; 102243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool ok = true; 10239d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org 10249d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org if (shared_info->is_arrow()) { 10259d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org Expression* expression = ParseExpression(false, &ok); 1026e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expression->IsFunctionLiteral()); 10279d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org result = expression->AsFunctionLiteral(); 10289d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org } else { 10299d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), 10309d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org false, // Strict mode name already checked. 10312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org shared_info->kind(), RelocInfo::kNoPosition, 10329d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org function_type, 10339d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org FunctionLiteral::NORMAL_ARITY, &ok); 10349d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org } 103543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure the results agree. 1036e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ok == (result != NULL)); 103743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 103843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 103943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure the target stack is empty. 1040e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(target_stack_ == NULL); 104143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 104221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org if (result != NULL) { 10434d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org Handle<String> inferred_name(shared_info->inferred_name()); 1044a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org result->set_inferred_name(inferred_name); 104543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 104643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 104743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 104843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1049f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 1050fa943b736b1d996084393011529d568165bb5d83lrn@chromium.orgvoid* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1051b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org int end_token, bool is_eval, bool is_global, 1052b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Scope** eval_scope, bool* ok) { 105343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // SourceElements :: 1054f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // (ModuleElement)* <end_token> 105543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Allocate a target stack to use for this set of source 105743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // elements. This way, all scripts and functions get their own 105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // target stack thus avoiding illegal breaks and continues across 105943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // functions. 1060e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org TargetScope scope(&this->target_stack_); 106143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1062e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(processor != NULL); 10630a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org bool directive_prologue = true; // Parsing directive prologue. 10640a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 106543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != end_token) { 10660a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (directive_prologue && peek() != Token::STRING) { 10670a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; 10680a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 10690a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 1070f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scanner::Location token_loc = scanner()->peek_location(); 107133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Statement* stat; 107233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (is_global && !is_eval) { 107333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org stat = ParseModuleElement(NULL, CHECK_OK); 107433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } else { 107533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org stat = ParseBlockElement(NULL, CHECK_OK); 107633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 10770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (stat == NULL || stat->IsEmpty()) { 10780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; // End of directive prologue. 10790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org continue; 10800a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 10810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 10820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (directive_prologue) { 10830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // A shot at a directive. 1084f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ExpressionStatement* e_stat; 1085f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Literal* literal; 10860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Still processing directive prologue? 10870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if ((e_stat = stat->AsExpressionStatement()) != NULL && 10880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org (literal = e_stat->expression()->AsLiteral()) != NULL && 108908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org literal->raw_value()->IsString()) { 10905de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org // Check "use strict" directive (ES5 14.1) and "use asm" directive. Only 10915de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org // one can be present. 1092486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (strict_mode() == SLOPPY && 109308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org literal->raw_value()->AsString() == 10946313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->use_strict_string() && 10955de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org token_loc.end_pos - token_loc.beg_pos == 10966313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->use_strict_string()->length() + 2) { 10972c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // TODO(mstarzinger): Global strict eval calls, need their own scope 10982c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // as specified in ES5 10.4.2(3). The correct fix would be to always 10992c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // add this scope in DoParseProgram(), but that requires adaptations 11002c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // all over the code base, so we go with a quick-fix for now. 1101cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org // In the same manner, we have to patch the parsing mode. 1102f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (is_eval && !scope_->is_eval_scope()) { 1103e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(scope_->is_global_scope()); 1104f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* scope = NewScope(scope_, EVAL_SCOPE); 1105f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope->set_start_position(scope_->start_position()); 1106f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope->set_end_position(scope_->end_position()); 1107f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_ = scope; 1108b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org if (eval_scope != NULL) { 1109b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // Caller will correct the positions of the ad hoc eval scope. 1110b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org *eval_scope = scope; 1111b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org } 1112cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org mode_ = PARSE_EAGERLY; 11132c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } 1114486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org scope_->SetStrictMode(STRICT); 11150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // "use strict" is the only directive for now. 11160a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; 11175de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org } else if (literal->raw_value()->AsString() == 11186313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->use_asm_string() && 11195de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org token_loc.end_pos - token_loc.beg_pos == 11206313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->use_asm_string()->length() + 2) { 11215de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org // Store the usage count; The actual use counter on the isolate is 11225de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org // incremented after parsing is done. 11235de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org ++use_counts_[v8::Isolate::kUseAsm]; 1124a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org scope_->SetAsmModule(); 11250a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 11260a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 11270a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // End of the directive prologue. 11280a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; 11290a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 11300a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 11310a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 11327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org processor->Add(stat, zone()); 113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1134911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 113543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; 113643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 113743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 113843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 113908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels, 1140f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org bool* ok) { 1141f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // (Ecma 262 5th Edition, clause 14): 1142f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // SourceElement: 1143f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Statement 1144f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // FunctionDeclaration 1145f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // 1146f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // In harmony mode we allow additionally the following productions 1147f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModuleElement: 1148f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // LetDeclaration 1149f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ConstDeclaration 1150f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModuleDeclaration 1151f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ImportDeclaration 1152f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ExportDeclaration 1153f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // GeneratorDeclaration 1154f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1155f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org switch (peek()) { 1156f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::FUNCTION: 1157812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseFunctionDeclaration(NULL, ok); 1158a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org case Token::CLASS: 1159a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return ParseClassDeclaration(NULL, ok); 1160f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::IMPORT: 1161f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseImportDeclaration(ok); 1162f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::EXPORT: 1163f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseExportDeclaration(ok); 116470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org case Token::CONST: 116570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return ParseVariableStatement(kModuleElement, NULL, ok); 116670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org case Token::LET: 1167e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(allow_harmony_scoping()); 116870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (strict_mode() == STRICT) { 116970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return ParseVariableStatement(kModuleElement, NULL, ok); 117070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 117170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // Fall through. 1172a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org default: { 1173a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org Statement* stmt = ParseStatement(labels, CHECK_OK); 1174a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org // Handle 'module' as a context-sensitive keyword. 1175a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org if (FLAG_harmony_modules && 1176a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org peek() == Token::IDENTIFIER && 1177f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org !scanner()->HasAnyLineTerminatorBeforeNext() && 1178a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org stmt != NULL) { 1179a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org ExpressionStatement* estmt = stmt->AsExpressionStatement(); 118008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL && 118108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org estmt->expression()->AsVariableProxy()->raw_name() == 11826313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->module_string() && 1183f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org !scanner()->literal_contains_escapes()) { 1184812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseModuleDeclaration(NULL, ok); 1185a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 1186a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 1187a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org return stmt; 1188a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 1189f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1190f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1191f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1192f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 119308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseModuleDeclaration(ZoneList<const AstRawString*>* names, 119408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool* ok) { 1195f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModuleDeclaration: 1196f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // 'module' Identifier Module 1197f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1198a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 119908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = 120008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 1201bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1202bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1203bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 120408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org PrintF("# Module %.*s ", name->length(), name->raw_data()); 1205bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1206bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1207812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* module = ParseModule(CHECK_OK); 12088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); 1209812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1210f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org factory()->NewModuleDeclaration(proxy, module, scope_, pos); 1211812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 1212812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1213bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1214bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 121508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org PrintF("# Module %.*s ", name->length(), name->raw_data()); 1216bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 121708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org PrintF("module %.*s: ", name->length(), name->raw_data()); 1218bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com module->interface()->Print(); 1219bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1220bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1221bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 12227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (names) names->Add(name, zone()); 122381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org if (module->body() == NULL) 1224a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewEmptyStatement(pos); 122581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org else 1226a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewModuleStatement(proxy, module->body(), pos); 1227f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1228f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1229f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1230f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModule(bool* ok) { 1231f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Module: 1232f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // '{' ModuleElement '}' 1233812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // '=' ModulePath ';' 1234812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'at' String ';' 1235f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1236f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org switch (peek()) { 1237f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::LBRACE: 1238f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseModuleLiteral(ok); 1239f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1240812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::ASSIGN: { 1241f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::ASSIGN, CHECK_OK); 1242812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* result = ParseModulePath(CHECK_OK); 1243812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1244812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return result; 1245812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1246f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1247812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org default: { 12481fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ExpectContextualKeyword(CStrVector("at"), CHECK_OK); 1249812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* result = ParseModuleUrl(CHECK_OK); 1250812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1251812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return result; 1252812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1253f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1254f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1255f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1256f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1257f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleLiteral(bool* ok) { 1258f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Module: 1259f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // '{' ModuleElement '}' 1260f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1261a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 1262f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Construct block expecting 16 statements. 1263a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); 1264bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1265bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) PrintF("# Literal "); 1266bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1267f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* scope = NewScope(scope_, MODULE_SCOPE); 1268f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1269f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::LBRACE, CHECK_OK); 1270f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope->set_start_position(scanner()->location().beg_pos); 1271486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org scope->SetStrictMode(STRICT); 1272f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1273f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org { 1274f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org BlockState block_state(&scope_, scope); 12757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector collector(zone()); 1276f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Target target(&this->target_stack_, &collector); 1277f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Target target_body(&this->target_stack_, body); 1278f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1279f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org while (peek() != Token::RBRACE) { 1280f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Statement* stat = ParseModuleElement(NULL, CHECK_OK); 1281f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (stat && !stat->IsEmpty()) { 1282400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body->AddStatement(stat, zone()); 1283f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1284f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1285f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1286f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1287f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::RBRACE, CHECK_OK); 1288f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope->set_end_position(scanner()->location().end_pos); 1289ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com body->set_scope(scope); 1290bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 129181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // Check that all exports are bound. 1292ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Interface* interface = scope->interface(); 129381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org for (Interface::Iterator it = interface->iterator(); 129481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org !it.done(); it.Advance()) { 1295fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org if (scope->LookupLocal(it.name()) == NULL) { 1296285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ParserTraits::ReportMessage("module_export_undefined", it.name()); 129781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org *ok = false; 129881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org return NULL; 129981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org } 130081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org } 130181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org 1302ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com interface->MakeModule(ok); 1303e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(*ok); 1304ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com interface->Freeze(ok); 1305e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(*ok); 1306a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewModuleLiteral(body, interface, pos); 1307f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1308f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1309f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1310f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModulePath(bool* ok) { 1311f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModulePath: 1312f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Identifier 1313f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModulePath '.' Identifier 1314f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1315a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 1316f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Module* result = ParseModuleVariable(CHECK_OK); 1317f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org while (Check(Token::PERIOD)) { 131808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = ParseIdentifierName(CHECK_OK); 1319bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1320bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 132108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org PrintF("# Path .%.*s ", name->length(), name->raw_data()); 1322bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1323a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Module* member = factory()->NewModulePath(result, name, pos); 13247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org result->interface()->Add(name, member->interface(), zone(), ok); 1325bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (!*ok) { 1326bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1327bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 132808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data()); 1329bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("result: "); 1330bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com result->interface()->Print(); 1331bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("member: "); 1332bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com member->interface()->Print(); 1333bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1334bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1335285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ParserTraits::ReportMessage("invalid_module_path", name); 1336bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com return NULL; 1337bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1338bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com result = member; 1339f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1340f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1341f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return result; 1342f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1343f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1344f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1345f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleVariable(bool* ok) { 1346f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModulePath: 1347f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Identifier 1348f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1349a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 135008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = 135108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 1352bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1353bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 135408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org PrintF("# Module variable %.*s ", name->length(), name->raw_data()); 1355bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1356f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org VariableProxy* proxy = scope_->NewUnresolved( 135728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org factory(), name, Interface::NewModule(zone()), 1358f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scanner()->location().beg_pos); 1359bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1360a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewModuleVariable(proxy, pos); 1361f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1362f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1363f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1364f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleUrl(bool* ok) { 1365f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Module: 1366812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // String 1367f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1368a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 1369f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::STRING, CHECK_OK); 137008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* symbol = GetSymbol(scanner()); 1371f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1372bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // TODO(ES6): Request JS resource from environment... 1373bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1374bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1375bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) PrintF("# Url "); 1376bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1377ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 13788e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Create an empty literal as long as the feature isn't finished. 13798e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org USE(symbol); 1380f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* scope = NewScope(scope_, MODULE_SCOPE); 1381a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 13828e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org body->set_scope(scope); 13838e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Interface* interface = scope->interface(); 1384a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Module* result = factory()->NewModuleLiteral(body, interface, pos); 1385ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com interface->Freeze(ok); 1386e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(*ok); 138781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org interface->Unify(scope->interface(), zone(), ok); 1388e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(*ok); 1389ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com return result; 1390f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1391f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1392f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1393812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgModule* Parser::ParseModuleSpecifier(bool* ok) { 1394812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ModuleSpecifier: 1395812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // String 1396812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ModulePath 1397812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1398812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org if (peek() == Token::STRING) { 1399812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseModuleUrl(ok); 1400812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } else { 1401812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseModulePath(ok); 1402812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1403812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 1404812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1405812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1406f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgBlock* Parser::ParseImportDeclaration(bool* ok) { 1407812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ImportDeclaration: 1408812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' 1409812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 1410812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // TODO(ES6): implement destructuring ImportSpecifiers 1411812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1412a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 1413812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Expect(Token::IMPORT, CHECK_OK); 141408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<const AstRawString*> names(1, zone()); 1415812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 141608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = ParseIdentifierName(CHECK_OK); 14177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1418812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org while (peek() == Token::COMMA) { 1419812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Consume(Token::COMMA); 1420812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org name = ParseIdentifierName(CHECK_OK); 14217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1422812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1423812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 14241fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ExpectContextualKeyword(CStrVector("from"), CHECK_OK); 1425812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* module = ParseModuleSpecifier(CHECK_OK); 1426812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1427812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1428812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Generate a separate declaration for each identifier. 1429812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // TODO(ES6): once we implement destructuring, make that one declaration. 1430a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); 1431812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org for (int i = 0; i < names.length(); ++i) { 1432bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1433bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 143408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org PrintF("# Import %.*s ", name->length(), name->raw_data()); 1435bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 14367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Interface* interface = Interface::NewUnknown(zone()); 14377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org module->interface()->Add(names[i], interface, zone(), ok); 1438bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (!*ok) { 1439bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1440bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 144108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(), 144208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org name->raw_data()); 1443bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("module: "); 1444bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com module->interface()->Print(); 1445bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1446bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1447285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ParserTraits::ReportMessage("invalid_module_path", name); 1448bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com return NULL; 1449bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1450bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com VariableProxy* proxy = NewUnresolved(names[i], LET, interface); 1451812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1452f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org factory()->NewImportDeclaration(proxy, module, scope_, pos); 1453812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 1454812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1455812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1456812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return block; 1457f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1458f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1459f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1460812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgStatement* Parser::ParseExportDeclaration(bool* ok) { 1461812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ExportDeclaration: 1462812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' Identifier (',' Identifier)* ';' 1463812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' VariableDeclaration 1464812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' FunctionDeclaration 1465f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // 'export' GeneratorDeclaration 1466812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' ModuleDeclaration 1467812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 1468812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // TODO(ES6): implement structuring ExportSpecifiers 1469812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1470812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Expect(Token::EXPORT, CHECK_OK); 1471812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1472812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Statement* result = NULL; 147308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<const AstRawString*> names(1, zone()); 1474812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org switch (peek()) { 1475812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::IDENTIFIER: { 1476a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 147708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = 14788297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 1479812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Handle 'module' as a context-sensitive keyword. 14806313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org if (name != ast_value_factory()->module_string()) { 14817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1482812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org while (peek() == Token::COMMA) { 1483812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Consume(Token::COMMA); 14848297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 14857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1486812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1487812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1488a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewEmptyStatement(pos); 1489812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } else { 1490812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org result = ParseModuleDeclaration(&names, CHECK_OK); 1491812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1492812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 1493812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1494812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1495812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::FUNCTION: 1496812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org result = ParseFunctionDeclaration(&names, CHECK_OK); 1497812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 1498812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1499a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org case Token::CLASS: 1500a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org result = ParseClassDeclaration(&names, CHECK_OK); 1501a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org break; 1502a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 1503812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::VAR: 1504812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::LET: 1505812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::CONST: 1506812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); 1507812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 1508812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1509812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org default: 1510812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org *ok = false; 1511f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ReportUnexpectedToken(scanner()->current_token()); 1512812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return NULL; 1513812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1514812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 15157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Every export of a module may be assigned. 15167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (int i = 0; i < names.length(); ++i) { 15177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Variable* var = scope_->Lookup(names[i]); 15187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (var == NULL) { 15197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(sigurds) This is an export that has no definition yet, 15207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // not clear what to do in this case. 15217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org continue; 15227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 15237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (!IsImmutableVariableMode(var->mode())) { 15247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org var->set_maybe_assigned(); 15257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 15267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 15277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1528bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Extract declared names into export declarations and interface. 1529f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Interface* interface = scope_->interface(); 1530812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org for (int i = 0; i < names.length(); ++i) { 1531bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1532bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 153308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data()); 1534bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 15357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Interface* inner = Interface::NewUnknown(zone()); 15367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org interface->Add(names[i], inner, zone(), CHECK_OK); 15377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (!*ok) 15387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org return NULL; 1539bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com VariableProxy* proxy = NewUnresolved(names[i], LET, inner); 1540bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com USE(proxy); 1541bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // TODO(rossberg): Rethink whether we actually need to store export 1542bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // declarations (for compilation?). 1543bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // ExportDeclaration* declaration = 1544f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // factory()->NewExportDeclaration(proxy, scope_, position); 1545f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // scope_->AddDeclaration(declaration); 1546812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1547812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1548e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result != NULL); 1549812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return result; 1550f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1551f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1552f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 155308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels, 1554f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org bool* ok) { 1555f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // (Ecma 262 5th Edition, clause 14): 1556f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // SourceElement: 1557f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Statement 1558f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // FunctionDeclaration 1559f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // 1560f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // In harmony mode we allow additionally the following productions 1561f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // BlockElement (aka SourceElement): 1562f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // LetDeclaration 1563f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ConstDeclaration 1564f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // GeneratorDeclaration 1565a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // ClassDeclaration 1566f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1567f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org switch (peek()) { 1568f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::FUNCTION: 1569812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseFunctionDeclaration(NULL, ok); 1570a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org case Token::CLASS: 1571a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return ParseClassDeclaration(NULL, ok); 1572f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::CONST: 1573812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseVariableStatement(kModuleElement, NULL, ok); 157470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org case Token::LET: 1575e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(allow_harmony_scoping()); 157670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (strict_mode() == STRICT) { 157770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return ParseVariableStatement(kModuleElement, NULL, ok); 157870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 157970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // Fall through. 1580f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org default: 1581f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseStatement(labels, ok); 1582f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1583f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1584f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1585f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 158608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, 158708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool* ok) { 158843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Statement :: 158943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Block 159043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableStatement 159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // EmptyStatement 159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ExpressionStatement 159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IfStatement 159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IterationStatement 159543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ContinueStatement 159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // BreakStatement 159743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ReturnStatement 159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WithStatement 159943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LabelledStatement 160043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // SwitchStatement 160143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ThrowStatement 160243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TryStatement 160343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // DebuggerStatement 160443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 160543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note: Since labels can only be used by 'break' and 'continue' 160643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // statements, which themselves are only valid within blocks, 160743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // iterations or 'switch' statements (i.e., BreakableStatements), 160843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // labels can be simply ignored in all other cases; except for 16093291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // trivial labeled break statements 'label: break label' which is 161043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parsed into an empty statement. 161143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (peek()) { 161243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LBRACE: 161343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return ParseBlock(labels, ok); 161443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 161543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SEMICOLON: 161643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 1617a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewEmptyStatement(RelocInfo::kNoPosition); 161843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 161943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::IF: 1620a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseIfStatement(labels, ok); 162143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::DO: 1623a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseDoWhileStatement(labels, ok); 162443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::WHILE: 1626a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseWhileStatement(labels, ok); 162743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::FOR: 1629a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseForStatement(labels, ok); 163043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 163143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::CONTINUE: 1632a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseContinueStatement(ok); 163343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 163443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::BREAK: 1635a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseBreakStatement(labels, ok); 163643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 163743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::RETURN: 1638a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseReturnStatement(ok); 163943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::WITH: 1641a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseWithStatement(labels, ok); 164243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SWITCH: 1644a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseSwitchStatement(labels, ok); 164543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::THROW: 1647a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseThrowStatement(ok); 164843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::TRY: { 165043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // NOTE: It is somewhat complicated to have labels on 165143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // try-statements. When breaking out of a try-finally statement, 165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // one must take great care not to treat it as a 165343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // fall-through. It is much easier just to wrap the entire 165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // try-statement in a statement block and put the labels there 1655a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* result = 1656a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition); 1657e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, result); 165843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TryStatement* statement = ParseTryStatement(CHECK_OK); 1659400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org if (result) result->AddStatement(statement, zone()); 166043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 166143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 166243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16639ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org case Token::FUNCTION: { 1664c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // FunctionDeclaration is only allowed in the context of SourceElements 1665c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // (Ecma 262 5th Edition, clause 14): 1666c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // SourceElement: 1667c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Statement 1668c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // FunctionDeclaration 1669c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Common language extension is to allow function declaration in place 1670c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of any statement. This language extension is disabled in strict mode. 1671f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // 1672f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // In Harmony mode, this case also handles the extension: 1673f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Statement: 1674f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // GeneratorDeclaration 1675486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (strict_mode() == STRICT) { 1676f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ReportMessageAt(scanner()->peek_location(), "strict_function"); 16779ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org *ok = false; 16789ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org return NULL; 16799ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 1680812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseFunctionDeclaration(NULL, ok); 16819ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 168243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1683a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org case Token::CLASS: 1684a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return ParseClassDeclaration(NULL, ok); 1685a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 168643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::DEBUGGER: 1687a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseDebuggerStatement(ok); 168843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 168970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org case Token::VAR: 169070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org case Token::CONST: 169170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return ParseVariableStatement(kStatement, NULL, ok); 169270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 169370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org case Token::LET: 1694e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(allow_harmony_scoping()); 169570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (strict_mode() == STRICT) { 169670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return ParseVariableStatement(kStatement, NULL, ok); 169770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 169870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // Fall through. 169943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 1700a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseExpressionOrLabelledStatement(labels, ok); 170143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 170243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 170343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgVariableProxy* Parser::NewUnresolved(const AstRawString* name, 170608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org VariableMode mode, Interface* interface) { 1707b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // If we are inside a function, a declaration of a var/const variable is a 1708b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // truly local variable, and the scope of the variable is always the function 1709b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // scope. 1710394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Let/const variables in harmony mode are always added to the immediately 1711394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // enclosing scope. 1712812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return DeclarationScope(mode)->NewUnresolved( 1713a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory(), name, interface, position()); 1714812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 1715812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1716812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1717812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { 1718bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com VariableProxy* proxy = declaration->proxy(); 1719e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(proxy->raw_name() != NULL); 172008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = proxy->raw_name(); 1721812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org VariableMode mode = declaration->mode(); 1722812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Scope* declaration_scope = DeclarationScope(mode); 1723812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Variable* var = NULL; 172443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 172581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // If a suitable scope exists, then we can statically declare this 172643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // variable and also set its mode. In any case, a Declaration node 172743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will be added to the scope so that the declaration can be added 172843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to the corresponding activation frame at runtime if necessary. 172943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // For instance declarations inside an eval scope need to be added 173043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to the calling function context. 17318e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org // Similarly, strict mode eval scope does not leak variable declarations to 17328e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org // the caller's scope so we declare all locals, too. 17334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (declaration_scope->is_function_scope() || 1734486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org declaration_scope->is_strict_eval_scope() || 1735f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org declaration_scope->is_block_scope() || 1736bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com declaration_scope->is_module_scope() || 1737355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org declaration_scope->is_global_scope()) { 173881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // Declare the variable in the declaration scope. 1739355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // For the global scope, we have to check for collisions with earlier 1740355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // (i.e., enclosing) global scopes, to maintain the illusion of a single 1741355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // global scope. 1742355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org var = declaration_scope->is_global_scope() 1743355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org ? declaration_scope->Lookup(name) 1744fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org : declaration_scope->LookupLocal(name); 174543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (var == NULL) { 174643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Declare the name. 17477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org var = declaration_scope->DeclareLocal(name, mode, 17487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org declaration->initialization(), 17497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org kNotAssigned, proxy->interface()); 175012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode()) 175112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && 175212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org !declaration_scope->is_global_scope())) { 17531805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // The name was declared in this scope before; check for conflicting 17541805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // re-declarations. We have a conflict if either of the declarations is 1755355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // not a var (in the global scope, we also have to ignore legacy const for 1756355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // compatibility). There is similar code in runtime.cc in the Declare 175712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // functions. The function CheckConflictingVarDeclarations checks for 17581805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // var and let bindings from different scopes whereas this is a check for 17591805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // conflicting declarations within the same scope. This check also covers 1760355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // the special case 17611805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // 17621805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // function () { let x; { var x; } } 17631805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // 17641805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // because the var declaration is hoisted to the function scope where 'x' 17651805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // is already bound. 1766e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsDeclaredVariableMode(var->mode())); 1767a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if (allow_harmony_scoping() && strict_mode() == STRICT) { 1768486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // In harmony we treat re-declarations as early errors. See 1769355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // ES5 16 for a definition of early errors. 1770285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ParserTraits::ReportMessage("var_redeclaration", name); 1771355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org *ok = false; 1772355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org return; 177343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 17744edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org Expression* expression = NewThrowTypeError( 17754edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org "var_redeclaration", name, declaration->position()); 1776355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org declaration_scope->SetIllegalRedeclaration(expression); 1777248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org } else if (mode == VAR) { 1778248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org var->set_maybe_assigned(); 177943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 178043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 178143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 178243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We add a declaration node for every declaration. The compiler 178343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will only generate code if necessary. In particular, declarations 178443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // for inner local variables that do not represent functions won't 178543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // result in any generated code. 178643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 178743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that we always add an unresolved proxy even if it's not 178843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // used, simply because we don't know in this method (w/o extra 178943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parameters) if the proxy is needed or not. The proxy will be 179043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // bound during variable resolution time unless it was pre-bound 179143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // below. 179243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 179343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WARNING: This will lead to multiple declaration nodes for the 179443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // same variable if it is declared several times. This is not a 179543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // semantic issue as long as we keep the source order, but it may be 179643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // a performance issue since it may lead to repeated 17979bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // RuntimeHidden_DeclareLookupSlot calls. 1798812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org declaration_scope->AddDeclaration(declaration); 179943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1800486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) { 180127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // For global const variables we bind the proxy to a variable. 1802e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(resolve); // should be set by all callers 18033e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org Variable::Kind kind = Variable::NORMAL; 18047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org var = new (zone()) 18057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Variable(declaration_scope, name, mode, true, kind, 18067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org kNeedsInitialization, kNotAssigned, proxy->interface()); 180727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } else if (declaration_scope->is_eval_scope() && 1808486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org declaration_scope->strict_mode() == SLOPPY) { 1809486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // For variable declarations in a sloppy eval scope the proxy is bound 181027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // to a lookup variable to force a dynamic declaration using the 18119bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // DeclareLookupSlot runtime function. 181227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Variable::Kind kind = Variable::NORMAL; 18137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(sigurds) figure out if kNotAssigned is OK here 18147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org var = new (zone()) Variable(declaration_scope, name, mode, true, kind, 18157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org declaration->initialization(), kNotAssigned, 18167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org proxy->interface()); 181727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org var->AllocateTo(Variable::LOOKUP, -1); 181827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org resolve = true; 181943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 182043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 182143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If requested and we have a local variable, bind the proxy to the variable 182243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // at parse-time. This is used for functions (and consts) declared inside 182343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // statements: the corresponding function (or const) variable must be in the 182443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function scope and not a statement-local scope, e.g. as provided with a 182543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'with' statement: 182643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 182743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // with (obj) { 182843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function f() {} 182943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // } 183043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 183143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // which is translated into: 183243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 183343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // with (obj) { 183443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // // in this case this is not: 'var f; f = function () {};' 183543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // var f = function () {}; 183643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // } 183743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 183843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that if 'f' is accessed from inside the 'with' statement, it 183943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will be allocated in the context (because we must be able to look 184043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // it up dynamically) but it will also be accessed statically, i.e., 184143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // with a context slot index and a context chain length for this 184243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // initialization code. Thus, inside the 'with' statement, we need 184343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // both access to the static and the dynamic context chain; the 184443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // runtime needs to provide both. 1845bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (resolve && var != NULL) { 1846bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com proxy->BindTo(var); 1847bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1848bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_harmony_modules) { 1849bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com bool ok; 1850bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 185108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org if (FLAG_print_interface_details) { 185208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org PrintF("# Declare %.*s ", var->raw_name()->length(), 185308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org var->raw_name()->raw_data()); 185408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org } 1855bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 18567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org proxy->interface()->Unify(var->interface(), zone(), &ok); 1857bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (!ok) { 1858bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1859bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 1860bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("DECLARE TYPE ERROR\n"); 1861bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("proxy: "); 1862bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com proxy->interface()->Print(); 1863bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("var: "); 1864bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com var->interface()->Print(); 1865bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1866bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1867285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ParserTraits::ReportMessage("module_type_error", name); 1868bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1869bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1870bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 187143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 187243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 187343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 187443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Language extension which is only enabled for source files loaded 187543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// through the API's extension mechanism. A native function 187643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// declaration is resolved by looking up the function through a 187743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// callback provided by the extension. 187843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseNativeDeclaration(bool* ok) { 1879a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 188043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::FUNCTION, CHECK_OK); 18818297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org // Allow "eval" or "arguments" for backward compatibility. 188208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 188343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 188443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool done = (peek() == Token::RPAREN); 188543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!done) { 18868297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 188743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen done = (peek() == Token::RPAREN); 1888fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (!done) { 1889fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org Expect(Token::COMMA, CHECK_OK); 1890fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org } 189143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 189243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 189343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SEMICOLON, CHECK_OK); 189443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 189543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure that the function containing the native declaration 189643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // isn't lazily compiled. The extension structures are only 189743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // accessible while parsing the first time not when reparsing 189843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // because of lazy compilation. 1899812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org DeclarationScope(VAR)->ForceEagerCompilation(); 190043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 190143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1240846): It's weird that native function declarations are 190243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // introduced dynamically when we meet their declarations, whereas 1903f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // other functions are set up when entering the surrounding scope. 190428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); 1905812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1906f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org factory()->NewVariableDeclaration(proxy, VAR, scope_, pos); 1907812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 1908a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( 1909a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org name, extension_, RelocInfo::kNoPosition); 1910b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewExpressionStatement( 1911b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewAssignment( 1912a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), 1913a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos); 191443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 191543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 191643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 191708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseFunctionDeclaration( 191808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<const AstRawString*>* names, bool* ok) { 1919c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // FunctionDeclaration :: 1920c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 1921f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // GeneratorDeclaration :: 1922f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // 'function' '*' Identifier '(' FormalParameterListopt ')' 1923f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // '{' FunctionBody '}' 192443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::FUNCTION, CHECK_OK); 1925a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 1926d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org bool is_generator = Check(Token::MUL); 192704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool is_strict_reserved = false; 192808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = ParseIdentifierOrStrictReservedWord( 192904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org &is_strict_reserved, CHECK_OK); 19302c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org FunctionLiteral* fun = 19312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved, 19322c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org is_generator ? FunctionKind::kGeneratorFunction 19332c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org : FunctionKind::kNormalFunction, 19342c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org pos, FunctionLiteral::DECLARATION, 19352c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org FunctionLiteral::NORMAL_ARITY, CHECK_OK); 1936c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Even if we're not at the top-level of the global or a function 1937355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // scope, we treat it as such and introduce the function with its 1938c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // initial value upon entering the corresponding scope. 193912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // In ES6, a function behaves as a lexical binding, except in the 194012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // global scope, or the initial scope of eval or another function. 1941355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org VariableMode mode = 194212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org allow_harmony_scoping() && strict_mode() == STRICT && 194312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org !(scope_->is_global_scope() || scope_->is_eval_scope() || 194412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org scope_->is_function_scope()) ? LET : VAR; 194528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); 1946812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1947f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); 1948812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 19497028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (names) names->Add(name, zone()); 1950a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewEmptyStatement(RelocInfo::kNoPosition); 195143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 195243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 195343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1954a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgStatement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, 1955a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org bool* ok) { 1956a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // ClassDeclaration :: 1957a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' 1958a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // 1959a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // A ClassDeclaration 1960a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // 1961a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // class C { ... } 1962a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // 1963a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // has the same semantics as: 1964a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // 1965a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // let C = class C { ... }; 1966a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // 1967a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // so rewrite it as such. 1968a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 1969a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Expect(Token::CLASS, CHECK_OK); 1970a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int pos = position(); 1971a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org bool is_strict_reserved = false; 1972a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org const AstRawString* name = 1973a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 1974a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Expression* value = ParseClassLiteral(name, scanner()->location(), 1975a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org is_strict_reserved, pos, CHECK_OK); 1976a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 1977a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Block* block = factory()->NewBlock(NULL, 1, true, pos); 1978a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org VariableMode mode = LET; 1979a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); 1980a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Declaration* declaration = 1981a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org factory()->NewVariableDeclaration(proxy, mode, scope_, pos); 1982a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Declare(declaration, true, CHECK_OK); 1983a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 1984a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Token::Value init_op = Token::INIT_LET; 1985a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); 1986a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org block->AddStatement( 1987a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), 1988a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org zone()); 1989a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 1990a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org if (names) names->Add(name, zone()); 1991a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return block; 1992a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org} 1993a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 1994a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 199508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgBlock* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { 1996a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if (allow_harmony_scoping() && strict_mode() == STRICT) { 1997486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org return ParseScopedBlock(labels, ok); 1998486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } 19994acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 200043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Block :: 200143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '{' Statement* '}' 200243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 200343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that a Block does not introduce a new execution scope! 200443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // (ECMA-262, 3rd, 12.2) 200543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 200643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Construct block expecting 16 statements. 2007a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* result = 2008a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); 2009e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, result); 201043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 201143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::RBRACE) { 201243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* stat = ParseStatement(NULL, CHECK_OK); 20136db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (stat && !stat->IsEmpty()) { 2014400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(stat, zone()); 20156db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 201643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 201743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACE, CHECK_OK); 201843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 201943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 202043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 202143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 202208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgBlock* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels, 202308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool* ok) { 2024f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // The harmony mode uses block elements instead of statements. 2025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // 2026c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Block :: 2027f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // '{' BlockElement* '}' 2028c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 20294acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Construct block expecting 16 statements. 2030a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* body = 2031a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); 2032f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); 20334acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 20344acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Parse the statements and collect escaping labels. 20354acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Expect(Token::LBRACE, CHECK_OK); 2036f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org block_scope->set_start_position(scanner()->location().beg_pos); 2037f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org { BlockState block_state(&scope_, block_scope); 20387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector collector(zone()); 2039394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Target target(&this->target_stack_, &collector); 20404acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Target target_body(&this->target_stack_, body); 20414acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 20424acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org while (peek() != Token::RBRACE) { 2043f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Statement* stat = ParseBlockElement(NULL, CHECK_OK); 20444acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (stat && !stat->IsEmpty()) { 2045400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body->AddStatement(stat, zone()); 20464acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 20474acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 20484acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 20494acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Expect(Token::RBRACE, CHECK_OK); 2050f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org block_scope->set_end_position(scanner()->location().end_pos); 20511805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org block_scope = block_scope->FinalizeBlockScope(); 2052ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com body->set_scope(block_scope); 2053486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return body; 20544acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org} 20554acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 20564acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 2057b645116853c677aca8a316381b87441ba6004f67danno@chromium.orgBlock* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 205808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<const AstRawString*>* names, 2059b645116853c677aca8a316381b87441ba6004f67danno@chromium.org bool* ok) { 206043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableStatement :: 206143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableDeclarations ';' 206243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 206308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* ignore; 2064f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Block* result = 2065812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); 206643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 206743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 206843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 206943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2070ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 207143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// If the variable declaration declares exactly one non-const 207278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// variable, then *out is set to that variable. In all other cases, 207378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// *out is untouched; in particular, it is the caller's responsibility 207443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to initialize it properly. This mechanism is used for the parsing 207543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// of 'for-in' loops. 2076394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comBlock* Parser::ParseVariableDeclarations( 2077394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com VariableDeclarationContext var_context, 2078394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com VariableDeclarationProperties* decl_props, 207908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<const AstRawString*>* names, 208008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString** out, 2081394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool* ok) { 208243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableDeclarations :: 2083394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] 2084394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2085394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // The ES6 Draft Rev3 specifies the following grammar for const declarations 2086394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2087394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ConstDeclaration :: 2088394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // const ConstBinding (',' ConstBinding)* ';' 2089394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ConstBinding :: 2090394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Identifier '=' AssignmentExpression 2091394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2092394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // TODO(ES6): 2093394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ConstBinding :: 2094394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // BindingPattern '=' AssignmentExpression 2095a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org 2096a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 2097b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org VariableMode mode = VAR; 209880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // True if the binding needs initialization. 'let' and 'const' declared 209980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // bindings are created uninitialized by their declaration nodes and 210080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // need initialization. 'var' declared bindings are always initialized 210180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // immediately by their declaration nodes. 210280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org bool needs_init = false; 210343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool is_const = false; 210480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Token::Value init_op = Token::INIT_VAR; 210543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::VAR) { 210643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::VAR); 210743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (peek() == Token::CONST) { 21081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: 21091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 21101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 21111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 21121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // * It is a Syntax Error if the code that matches this production is not 21131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // contained in extended code. 21141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 2115486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // However disallowing const in sloppy mode will break compatibility with 21161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // existing pages. Therefore we keep allowing const with the old 2117486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // non-harmony semantics in sloppy mode. 211843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::CONST); 2119486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org switch (strict_mode()) { 2120486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org case SLOPPY: 2121486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org mode = CONST_LEGACY; 2122486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org init_op = Token::INIT_CONST_LEGACY; 21231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org break; 2124486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org case STRICT: 2125a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if (allow_harmony_scoping()) { 2126486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (var_context == kStatement) { 2127486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // In strict mode 'const' declarations are only allowed in source 2128486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // element positions. 2129285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ReportMessage("unprotected_const"); 2130486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org *ok = false; 2131486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org return NULL; 2132486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } 2133486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org mode = CONST; 2134486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org init_op = Token::INIT_CONST; 2135486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } else { 2136285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ReportMessage("strict_const"); 21371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org *ok = false; 21381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return NULL; 21391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 21409ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 214143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen is_const = true; 214280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org needs_init = true; 214370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } else if (peek() == Token::LET && strict_mode() == STRICT) { 2144e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(allow_harmony_scoping()); 2145b645116853c677aca8a316381b87441ba6004f67danno@chromium.org Consume(Token::LET); 2146f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (var_context == kStatement) { 2147394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Let declarations are only allowed in source element positions. 2148285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ReportMessage("unprotected_let"); 2149b645116853c677aca8a316381b87441ba6004f67danno@chromium.org *ok = false; 2150b645116853c677aca8a316381b87441ba6004f67danno@chromium.org return NULL; 2151b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } 2152b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org mode = LET; 215380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org needs_init = true; 215480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org init_op = Token::INIT_LET; 215543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 215643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); // by current callers 215743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 215843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2159812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Scope* declaration_scope = DeclarationScope(mode); 2160812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 2161b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // The scope of a var/const declared variable anywhere inside a function 216243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 2163b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // transform a source-level var/const declaration into a (Function) 216443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Scope declaration, and rewrite the source-level initialization into an 216543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // assignment statement. We use a block to collect multiple assignments. 216643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 216743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We mark the block as initializer block because we don't want the 216843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // rewriter to add a '.result' assignment to such a block (to get compliant 216943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // behavior for code such as print(eval('var x = 7')), and for cosmetic 217043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // reasons when pretty-printing. Also, unless an assignment (initialization) 217143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is inside an initializer block, it is ignored. 217243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 217343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create new block with one expected declaration. 2174a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* block = factory()->NewBlock(NULL, 1, true, pos); 217543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int nvars = 0; // the number of variables declared 217608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = NULL; 217743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen do { 217865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Enter(); 217965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 218043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse variable name. 218143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (nvars > 0) Consume(Token::COMMA); 21828297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 218365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushVariableName(name); 218443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 218543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Declare variable. 218643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that we *always* must treat the initial value via a separate init 218743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // assignment for variables and constants because the value must be assigned 218843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // when the variable is encountered in the source. But the variable/constant 218943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is declared (and set to 'undefined') upon entering the function within 219043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // which the variable or constant is declared. Only function variables have 219143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // an initial value in the declaration (because they are initialized upon 219243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // entering the function). 219343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 219443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we have a const declaration, in an inner scope, the proxy is always 219543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // bound to the declared variable (independent of possibly surrounding with 219643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // statements). 2197394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // For let/const declarations in harmony mode, we can also immediately 2198394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // pre-resolve the proxy because it resides in the same scope as the 2199394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // declaration. 220028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org Interface* interface = 220128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org is_const ? Interface::NewConst() : Interface::NewValue(); 220228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org VariableProxy* proxy = NewUnresolved(name, mode, interface); 2203812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 2204f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org factory()->NewVariableDeclaration(proxy, mode, scope_, pos); 2205812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, mode != VAR, CHECK_OK); 220643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen nvars++; 22074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { 2208196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ReportMessage("too_many_variables"); 22097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org *ok = false; 22107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return NULL; 22117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 22127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (names) names->Add(name, zone()); 221343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 221443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse initialization expression if present and/or needed. A 221543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration of the form: 221643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 221743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // var v = x; 221843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 221943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is syntactic sugar for: 222043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 222143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // var v; v = x; 222243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 2223f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // In particular, we need to re-lookup 'v' (in scope_, not 22244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // declaration_scope) as it may be a different 'v' than the 'v' in the 22254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // declaration (e.g., if we are inside a 'with' statement or 'catch' 22264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // block). 222743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 222843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // However, note that const declarations are different! A const 222943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration of the form: 223043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 223143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // const c = x; 223243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 223343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is *not* syntactic sugar for: 223443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 223543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // const c; c = x; 223643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 223743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The "variable" c initialized to x is the same as the declared 223843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // one - there is no re-lookup (see the last parameter of the 223943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Declare() call above). 224043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2241f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* initialization_scope = is_const ? declaration_scope : scope_; 224243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* value = NULL; 2243a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = -1; 2244394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Harmony consts have non-optional initializers. 2245486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (peek() == Token::ASSIGN || mode == CONST) { 224643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::ASSIGN, CHECK_OK); 2247a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos = position(); 2248b645116853c677aca8a316381b87441ba6004f67danno@chromium.org value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 224965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Don't infer if it is "a = function(){...}();"-like expression. 225004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (fni_ != NULL && 225104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org value->AsCall() == NULL && 225204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org value->AsCallNew() == NULL) { 225304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org fni_->Infer(); 2254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fni_->RemoveLastFunction(); 225604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 2257394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (decl_props != NULL) *decl_props = kHasInitializers; 225843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 225943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2260c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Record the end position of the initializer. 2261c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org if (proxy->var() != NULL) { 2262a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org proxy->var()->set_initializer_position(position()); 2263c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org } 2264c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 226580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Make sure that 'const x' and 'let x' initialize 'x' to undefined. 226680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org if (value == NULL && needs_init) { 2267a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org value = GetLiteralUndefined(position()); 226843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 226943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 227043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Global variable declarations must be compiled in a specific 227143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // way. When the script containing the global variable declaration 227243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is entered, the global variable must be declared, so that if it 2273ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // doesn't exist (on the global object itself, see ES5 errata) it 227443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // gets created with an initial undefined value. This is handled 227543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // by the declarations part of the function representing the 227643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // top-level global code; see Runtime::DeclareGlobalVariable. If 227743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // it already exists (in the object or in a prototype), it is 227843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // *not* touched until the variable declaration statement is 227943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // executed. 228043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 228143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Executing the variable declaration statement will always 228212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // guarantee to give the global object an own property. 228312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // This way, global variable declarations can shadow 228443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // properties in the prototype chain, but only after the variable 228543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration statement has been executed. This is important in 228643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // browsers where the global object (window) has lots of 228743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // properties defined in prototype objects. 2288355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org if (initialization_scope->is_global_scope() && 2289355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org !IsLexicalVariableMode(mode)) { 229043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute the arguments for the runtime call. 22917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Expression*>* arguments = 22927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<Expression*>(3, zone()); 2293c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // We have at least 1 parameter. 229408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org arguments->Add(factory()->NewStringLiteral(name, pos), zone()); 229543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CallRuntime* initialize; 22969ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 229743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (is_const) { 22987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org arguments->Add(value, zone()); 22999ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org value = NULL; // zap the value to avoid the unnecessary assignment 23009ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 23019ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Construct the call to Runtime_InitializeConstGlobal 23029ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // and add it to the initialization statement block. 23039ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Note that the function does different things depending on 23049ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // the number of arguments (1 or 2). 2305b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org initialize = factory()->NewCallRuntime( 23066313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->initialize_const_global_string(), 23076313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Runtime::FunctionForId(Runtime::kInitializeConstGlobal), arguments, 23086313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org pos); 230943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 23109ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Add strict mode. 23119ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // We may want to pass singleton to avoid Literal allocations. 2312486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org StrictMode strict_mode = initialization_scope->strict_mode(); 2313486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); 23149ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 23159ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Be careful not to assign a value to the global variable if 23169ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // we're in a with. The initialization value should not 23179ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // necessarily be stored in the global object in that case, 23189ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // which is why we need to generate a separate assignment node. 23199ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org if (value != NULL && !inside_with()) { 23207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org arguments->Add(value, zone()); 23219ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org value = NULL; // zap the value to avoid the unnecessary assignment 23229bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // Construct the call to Runtime_InitializeVarGlobal 23239bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // and add it to the initialization statement block. 23249bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org initialize = factory()->NewCallRuntime( 23256313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->initialize_var_global_string(), 23269bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Runtime::FunctionForId(Runtime::kInitializeVarGlobal), arguments, 23279bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org pos); 23289bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org } else { 23299bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org initialize = NULL; 23309ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 233143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 23329ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 23339bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (initialize != NULL) { 23349bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org block->AddStatement(factory()->NewExpressionStatement( 23359bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org initialize, RelocInfo::kNoPosition), 23369bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org zone()); 23379bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org } 233827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } else if (needs_init) { 233927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // Constant initializations always assign to the declared constant which 234027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // is always at the function scope level. This is only relevant for 234127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // dynamically looked-up variables and constants (the start context for 234227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // constant lookups is always the function context, while it is the top 234327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // context for var declared variables). Sigh... 234427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // For 'let' and 'const' declared variables in harmony mode the 234527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // initialization also always assigns to the declared variable. 2346e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(proxy != NULL); 2347e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(proxy->var() != NULL); 2348e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value != NULL); 234927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Assignment* assignment = 2350a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewAssignment(init_op, proxy, value, pos); 2351a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org block->AddStatement( 2352a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), 2353a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org zone()); 235427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org value = NULL; 235543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 235643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2357486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Add an assignment node to the initialization statement block if we still 235827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // have a pending initialization value. 235943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (value != NULL) { 2360e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(mode == VAR); 236127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // 'var' initializations are simply assignments (with all the consequences 236227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // if they are inside a 'with' statement - they may change a 'with' object 236327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // property). 2364b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org VariableProxy* proxy = 236528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org initialization_scope->NewUnresolved(factory(), name, interface); 2366c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Assignment* assignment = 2367a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewAssignment(init_op, proxy, value, pos); 2368a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org block->AddStatement( 2369a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), 2370a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org zone()); 237143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 237265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 237365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Leave(); 237443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } while (peek() == Token::COMMA); 237543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // If there was a single non-const declaration, return it in the output 23774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // parameter for possible use by for/in. 23784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (nvars == 1 && !is_const) { 23794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org *out = name; 238043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 238143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 238243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return block; 238343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 238443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 238543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 238608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgstatic bool ContainsLabel(ZoneList<const AstRawString*>* labels, 238708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* label) { 2388e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(label != NULL); 23891e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org if (labels != NULL) { 23901e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org for (int i = labels->length(); i-- > 0; ) { 239108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org if (labels->at(i) == label) { 239243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 23931e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 23941e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 23951e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 239643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 239743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 239843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 239943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 240008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseExpressionOrLabelledStatement( 240108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<const AstRawString*>* labels, bool* ok) { 240243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ExpressionStatement | LabelledStatement :: 240343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expression ';' 240443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Identifier ':' Statement 2405a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 240683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org bool starts_with_idenfifier = peek_any_identifier(); 240743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expr = ParseExpression(true, CHECK_OK); 24087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && 240943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen expr->AsVariableProxy() != NULL && 241043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen !expr->AsVariableProxy()->is_this()) { 24114a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Expression is a single identifier, and not, e.g., a parenthesized 24124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // identifier. 241343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen VariableProxy* var = expr->AsVariableProxy(); 241408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* label = var->raw_name(); 241543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1240780): We don't check for redeclaration of labels 241643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // during preparsing since keeping track of the set of active 241743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // labels requires nontrivial changes to the way scopes are 241843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // structured. However, these are probably changes we want to 241943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // make later anyway so we should go back and fix this then. 2420fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { 2421285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ParserTraits::ReportMessage("label_redeclaration", label); 2422fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org *ok = false; 2423fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org return NULL; 242443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 24257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (labels == NULL) { 242608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org labels = new(zone()) ZoneList<const AstRawString*>(4, zone()); 24277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 24287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org labels->Add(label, zone()); 2429fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // Remove the "ghost" variable that turned out to be a label 2430fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // from the top scope. This way, we don't try to resolve it 2431fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // during the scope processing. 2432f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_->RemoveUnresolved(var); 243343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COLON, CHECK_OK); 243443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return ParseStatement(labels, ok); 243543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 243643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24377b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // If we have an extension, we allow a native function declaration. 24387b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // A native function declaration starts with "native function" with 24397b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // no line-terminator between the two words. 24406313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org if (extension_ != NULL && peek() == Token::FUNCTION && 24416313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && 24427b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org expr->AsVariableProxy() != NULL && 244308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org expr->AsVariableProxy()->raw_name() == 24446313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->native_string() && 2445f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org !scanner()->literal_contains_escapes()) { 24467b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org return ParseNativeDeclaration(ok); 24477b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 24487b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 2449a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org // Parsed expression statement, or the context-sensitive 'module' keyword. 2450a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org // Only expect semicolon in the former case. 24516313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER || 2452f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scanner()->HasAnyLineTerminatorBeforeNext() || 2453a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org expr->AsVariableProxy() == NULL || 245408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org expr->AsVariableProxy()->raw_name() != 24556313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->module_string() || 2456f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scanner()->literal_contains_escapes()) { 2457a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org ExpectSemicolon(CHECK_OK); 2458a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 2459a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewExpressionStatement(expr, pos); 246043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 246143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 246243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 246308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgIfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, 246408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool* ok) { 246543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IfStatement :: 246643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'if' '(' Expression ')' Statement ('else' Statement)? 246743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2468a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 246943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::IF, CHECK_OK); 247043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 247143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* condition = ParseExpression(true, CHECK_OK); 247243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 247343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* then_statement = ParseStatement(labels, CHECK_OK); 247443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* else_statement = NULL; 247543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::ELSE) { 247643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 247743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen else_statement = ParseStatement(labels, CHECK_OK); 2478fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org } else { 2479a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 248043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2481a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewIfStatement( 2482a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org condition, then_statement, else_statement, pos); 248343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 248443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 248543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 248643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseContinueStatement(bool* ok) { 248743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ContinueStatement :: 248843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'continue' Identifier? ';' 248943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2490a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 249143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::CONTINUE, CHECK_OK); 249208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* label = NULL; 249343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value tok = peek(); 2494f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!scanner()->HasAnyLineTerminatorBeforeNext() && 24959258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 24968297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org // ECMA allows "eval" or "arguments" as labels even in strict mode. 24978297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 249843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 249908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org IterationStatement* target = LookupContinueTarget(label, CHECK_OK); 2500fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (target == NULL) { 2501c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Illegal continue statement. 2502c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org const char* message = "illegal_continue"; 250308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org if (label != NULL) { 2504c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org message = "unknown_label"; 2505c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 2506196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ParserTraits::ReportMessage(message, label); 2507c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org *ok = false; 2508c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return NULL; 250943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 251043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 2511a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewContinueStatement(target, pos); 251243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 251343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 251443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 251508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels, 251608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool* ok) { 251743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // BreakStatement :: 251843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'break' Identifier? ';' 251943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2520a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 252143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::BREAK, CHECK_OK); 252208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* label = NULL; 252343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value tok = peek(); 2524f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!scanner()->HasAnyLineTerminatorBeforeNext() && 25259258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 25268297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org // ECMA allows "eval" or "arguments" as labels even in strict mode. 25278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 252843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 25293291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Parse labeled break statements that target themselves into 253043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // empty statements, e.g. 'l1: l2: l3: break l2;' 253108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org if (label != NULL && ContainsLabel(labels, label)) { 2532b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org ExpectSemicolon(CHECK_OK); 2533a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewEmptyStatement(pos); 253443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 253543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakableStatement* target = NULL; 2536fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org target = LookupBreakTarget(label, CHECK_OK); 2537fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (target == NULL) { 2538c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Illegal break statement. 2539c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org const char* message = "illegal_break"; 254008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org if (label != NULL) { 2541c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org message = "unknown_label"; 2542c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 2543196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ParserTraits::ReportMessage(message, label); 2544c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org *ok = false; 2545c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return NULL; 254643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 254743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 2548a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewBreakStatement(target, pos); 254943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 255043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 255143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 255243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseReturnStatement(bool* ok) { 255343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ReturnStatement :: 255443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'return' Expression? ';' 255543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2556a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org // Consume the return token. It is necessary to do that before 255743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // reporting any errors on it, because of the way errors are 255843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // reported (underlining). 255943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RETURN, CHECK_OK); 25604edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org Scanner::Location loc = scanner()->location(); 256143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 256264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Token::Value tok = peek(); 256364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Statement* result; 256477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Expression* return_value; 2565f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (scanner()->HasAnyLineTerminatorBeforeNext() || 256664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org tok == Token::SEMICOLON || 256764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org tok == Token::RBRACE || 256864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org tok == Token::EOS) { 2569a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return_value = GetLiteralUndefined(position()); 257064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 257177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org return_value = ParseExpression(true, CHECK_OK); 257277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 257377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org ExpectSemicolon(CHECK_OK); 257477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (is_generator()) { 257577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Expression* generator = factory()->NewVariableProxy( 2576f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org function_state_->generator_object_variable()); 257777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Expression* yield = factory()->NewYield( 2578ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org generator, return_value, Yield::kFinal, loc.beg_pos); 25794edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org result = factory()->NewExpressionStatement(yield, loc.beg_pos); 258077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 25814edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org result = factory()->NewReturnStatement(return_value, loc.beg_pos); 258264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 258364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 25844edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org Scope* decl_scope = scope_->DeclarationScope(); 25854edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { 25864edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org ReportMessageAt(loc, "illegal_return"); 25874edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org *ok = false; 25884edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org return NULL; 258943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 259064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org return result; 259143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 259243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 259343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 259408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels, 259508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool* ok) { 259643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WithStatement :: 259743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'with' '(' Expression ')' Statement 259843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 259943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::WITH, CHECK_OK); 2600a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 26010a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 2602486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (strict_mode() == STRICT) { 2603285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ReportMessage("strict_mode_with"); 26040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org *ok = false; 26050a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return NULL; 26060a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 26070a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 260843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 260943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expr = ParseExpression(true, CHECK_OK); 261043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 261143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2612f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_->DeclarationScope()->RecordWithStatement(); 2613f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* with_scope = NewScope(scope_, WITH_SCOPE); 2614394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Statement* stmt; 2615f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org { BlockState block_state(&scope_, with_scope); 2616f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org with_scope->set_start_position(scanner()->peek_location().beg_pos); 2617394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com stmt = ParseStatement(labels, CHECK_OK); 2618f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org with_scope->set_end_position(scanner()->location().end_pos); 2619394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 2620a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewWithStatement(with_scope, expr, stmt, pos); 262143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 262243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 262343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 262443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenCaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { 262543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // CaseClause :: 262643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'case' Expression ':' Statement* 262743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'default' ':' Statement* 262843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 262943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* label = NULL; // NULL expression indicates default case 263043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::CASE) { 263143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::CASE, CHECK_OK); 263243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen label = ParseExpression(true, CHECK_OK); 263343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 263443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::DEFAULT, CHECK_OK); 263543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (*default_seen_ptr) { 2636285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ReportMessage("multiple_defaults_in_switch"); 263743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 263843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 263943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 264043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *default_seen_ptr = true; 264143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 264243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COLON, CHECK_OK); 2643a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 26447028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Statement*>* statements = 26457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<Statement*>(5, zone()); 264643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::CASE && 264743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen peek() != Token::DEFAULT && 264843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen peek() != Token::RBRACE) { 264943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* stat = ParseStatement(NULL, CHECK_OK); 26507028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org statements->Add(stat, zone()); 265143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 265243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2653a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewCaseClause(label, statements, pos); 265443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 265543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 265643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 265708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgSwitchStatement* Parser::ParseSwitchStatement( 265808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<const AstRawString*>* labels, bool* ok) { 265943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // SwitchStatement :: 266043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'switch' '(' Expression ')' '{' CaseClause* '}' 266143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2662a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org SwitchStatement* statement = 2663a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewSwitchStatement(labels, peek_position()); 2664e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, statement); 266543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 266643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SWITCH, CHECK_OK); 266743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 266843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* tag = ParseExpression(true, CHECK_OK); 266943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 267043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 267143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool default_seen = false; 26727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone()); 267343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 267443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::RBRACE) { 267543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); 26767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org cases->Add(clause, zone()); 267743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 267843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACE, CHECK_OK); 267943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2680fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (statement) statement->Initialize(tag, cases); 268143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return statement; 268243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 268343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 268443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 268543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseThrowStatement(bool* ok) { 268643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ThrowStatement :: 268743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'throw' Expression ';' 268843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 268943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::THROW, CHECK_OK); 2690a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 2691f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (scanner()->HasAnyLineTerminatorBeforeNext()) { 2692285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ReportMessage("newline_after_throw"); 269343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 269443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 269543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 269643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* exception = ParseExpression(true, CHECK_OK); 269743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 269843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2699a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewExpressionStatement( 2700a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewThrow(exception, pos), pos); 270143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 270243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 270343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 270443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTryStatement* Parser::ParseTryStatement(bool* ok) { 270543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TryStatement :: 270643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'try' Block Catch 270743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'try' Block Finally 270843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'try' Block Catch Finally 270943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 271043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Catch :: 271143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'catch' '(' Identifier ')' Block 271243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 271343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Finally :: 271443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'finally' Block 271543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 271643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::TRY, CHECK_OK); 2717a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 271843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector try_collector(zone()); 272043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Block* try_block; 272143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27226d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org { Target target(&this->target_stack_, &try_collector); 272343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen try_block = ParseBlock(NULL, CHECK_OK); 272443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 272543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 272643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value tok = peek(); 272743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tok != Token::CATCH && tok != Token::FINALLY) { 2728285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ReportMessage("no_catch_or_finally"); 272943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 273043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 273143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 273243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 273343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we can break out from the catch block and there is a finally block, 27346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // then we will need to collect escaping targets from the catch 27356d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // block. Since we don't know yet if there will be a finally block, we 27366d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // always collect the targets. 27377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector catch_collector(zone()); 27384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Scope* catch_scope = NULL; 27394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Variable* catch_variable = NULL; 27406d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Block* catch_block = NULL; 274108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = NULL; 274243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tok == Token::CATCH) { 274343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::CATCH); 274443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 274543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 2746f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org catch_scope = NewScope(scope_, CATCH_SCOPE); 2747f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org catch_scope->set_start_position(scanner()->location().beg_pos); 27488297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 27490a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 275043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 275143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2752bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org Target target(&this->target_stack_, &catch_collector); 2753486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org VariableMode mode = 2754a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org allow_harmony_scoping() && strict_mode() == STRICT ? LET : VAR; 27557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org catch_variable = catch_scope->DeclareLocal(name, mode, kCreatedInitialized); 2756f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org BlockState block_state(&scope_, catch_scope); 2757bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org catch_block = ParseBlock(NULL, CHECK_OK); 2758bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org 2759f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org catch_scope->set_end_position(scanner()->location().end_pos); 276043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tok = peek(); 276143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 276243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27636d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Block* finally_block = NULL; 2764e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(tok == Token::FINALLY || catch_block != NULL); 2765bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org if (tok == Token::FINALLY) { 276643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::FINALLY); 276743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen finally_block = ParseBlock(NULL, CHECK_OK); 276843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 276943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 277043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Simplify the AST nodes by converting: 27716d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // 'try B0 catch B1 finally B2' 277243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to: 27736d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // 'try { try B0 catch B1 } finally B2' 277443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2775fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (catch_block != NULL && finally_block != NULL) { 27764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // If we have both, create an inner try/catch. 2777e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(catch_scope != NULL && catch_variable != NULL); 2778f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int index = function_state_->NextHandlerIndex(); 2779b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org TryCatchStatement* statement = factory()->NewTryCatchStatement( 2780a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org index, try_block, catch_scope, catch_variable, catch_block, 2781a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org RelocInfo::kNoPosition); 27826d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org statement->set_escaping_targets(try_collector.targets()); 2783a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 2784400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org try_block->AddStatement(statement, zone()); 27854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org catch_block = NULL; // Clear to indicate it's been handled. 278643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 278743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 278843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TryStatement* result = NULL; 2789fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (catch_block != NULL) { 2790e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(finally_block == NULL); 2791e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(catch_scope != NULL && catch_variable != NULL); 2792f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int index = function_state_->NextHandlerIndex(); 2793b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewTryCatchStatement( 2794a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org index, try_block, catch_scope, catch_variable, catch_block, pos); 2795fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org } else { 2796e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(finally_block != NULL); 2797f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int index = function_state_->NextHandlerIndex(); 2798a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewTryFinallyStatement( 2799a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org index, try_block, finally_block, pos); 28006d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // Combine the jump targets of the try block and the possible catch block. 28017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org try_collector.targets()->AddAll(*catch_collector.targets(), zone()); 280243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 280343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28046d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org result->set_escaping_targets(try_collector.targets()); 280543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 280643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 280743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 280843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 280908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgDoWhileStatement* Parser::ParseDoWhileStatement( 281008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<const AstRawString*>* labels, bool* ok) { 281143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // DoStatement :: 281243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'do' Statement 'while' '(' Expression ')' ';' 281343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2814a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org DoWhileStatement* loop = 2815a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewDoWhileStatement(labels, peek_position()); 2816e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 281743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 281843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::DO, CHECK_OK); 281943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 282043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::WHILE, CHECK_OK); 282143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 2822c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 282343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* cond = ParseExpression(true, CHECK_OK); 282443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 282543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 282643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Allow do-statements to be terminated with and without 282743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // semi-colons. This allows code such as 'do;while(0)return' to 282843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parse, which would not be the case if we had used the 282943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ExpectSemicolon() functionality here. 283043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 283143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28329d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (loop != NULL) loop->Initialize(cond, body); 283343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return loop; 283443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 283543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 283643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 283708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgWhileStatement* Parser::ParseWhileStatement( 283808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<const AstRawString*>* labels, bool* ok) { 283943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WhileStatement :: 284043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'while' '(' Expression ')' Statement 284143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2842a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); 2843e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 284443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 284543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::WHILE, CHECK_OK); 284643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 284743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* cond = ParseExpression(true, CHECK_OK); 284843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 284943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 285043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (loop != NULL) loop->Initialize(cond, body); 285243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return loop; 285343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 285443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 285543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 285641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgbool Parser::CheckInOrOf(bool accept_OF, 285741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ForEachStatement::VisitMode* visit_mode) { 28581fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org if (Check(Token::IN)) { 28591fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org *visit_mode = ForEachStatement::ENUMERATE; 28601fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return true; 28618640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) { 28621fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org *visit_mode = ForEachStatement::ITERATE; 28631fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return true; 28641fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 28651fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return false; 28661fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org} 28671fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 28681fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 28691fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid Parser::InitializeForEachStatement(ForEachStatement* stmt, 28701fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* each, 28711fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* subject, 28721fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Statement* body) { 28731fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForOfStatement* for_of = stmt->AsForOfStatement(); 28741fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 28751fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org if (for_of != NULL) { 2876f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Variable* iterator = scope_->DeclarationScope()->NewTemporary( 28776313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->dot_iterator_string()); 2878f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Variable* result = scope_->DeclarationScope()->NewTemporary( 28796313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->dot_result_string()); 28801fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 28811fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* assign_iterator; 28821fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* next_result; 28831fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_done; 28841fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* assign_each; 28851fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 2886f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org // var iterator = subject[Symbol.iterator](); 28873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org assign_iterator = factory()->NewAssignment( 28883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Token::ASSIGN, factory()->NewVariableProxy(iterator), 28893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org GetIterator(subject, factory()), RelocInfo::kNoPosition); 28901fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 28911fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // var result = iterator.next(); 28921fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org { 28931fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 289408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Expression* next_literal = factory()->NewStringLiteral( 28956313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->next_string(), RelocInfo::kNoPosition); 28961fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* next_property = factory()->NewProperty( 28971fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org iterator_proxy, next_literal, RelocInfo::kNoPosition); 28981fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ZoneList<Expression*>* next_arguments = 28991fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org new(zone()) ZoneList<Expression*>(0, zone()); 29001fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* next_call = factory()->NewCall( 29011fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org next_property, next_arguments, RelocInfo::kNoPosition); 29021fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_proxy = factory()->NewVariableProxy(result); 29031fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org next_result = factory()->NewAssignment( 29041fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); 29051fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 29061fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 29071fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // result.done 29081fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org { 290908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Expression* done_literal = factory()->NewStringLiteral( 29106313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->done_string(), RelocInfo::kNoPosition); 29111fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_proxy = factory()->NewVariableProxy(result); 29121fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org result_done = factory()->NewProperty( 29131fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org result_proxy, done_literal, RelocInfo::kNoPosition); 29141fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 29151fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 29161fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // each = result.value 29171fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org { 291808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Expression* value_literal = factory()->NewStringLiteral( 29196313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->value_string(), RelocInfo::kNoPosition); 29201fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_proxy = factory()->NewVariableProxy(result); 29211fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_value = factory()->NewProperty( 29221fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org result_proxy, value_literal, RelocInfo::kNoPosition); 29231fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org assign_each = factory()->NewAssignment( 29241fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); 29251fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 29261fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 29271fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org for_of->Initialize(each, subject, body, 29281845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org assign_iterator, 29291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org next_result, 29301845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org result_done, 29311845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org assign_each); 29321fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } else { 29331fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org stmt->Initialize(each, subject, body); 29341fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 29351fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org} 29361fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 29371fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 29387e6132b924829c353864933f29124419916db550machenbach@chromium.orgStatement* Parser::DesugarLetBindingsInForStatement( 293908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Scope* inner_scope, ZoneList<const AstRawString*>* names, 294008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ForStatement* loop, Statement* init, Expression* cond, Statement* next, 294108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Statement* body, bool* ok) { 29427e6132b924829c353864933f29124419916db550machenbach@chromium.org // ES6 13.6.3.4 specifies that on each loop iteration the let variables are 29437e6132b924829c353864933f29124419916db550machenbach@chromium.org // copied into a new environment. After copying, the "next" statement of the 29447e6132b924829c353864933f29124419916db550machenbach@chromium.org // loop is executed to update the loop variables. The loop condition is 29457e6132b924829c353864933f29124419916db550machenbach@chromium.org // checked and the loop body is executed. 29467e6132b924829c353864933f29124419916db550machenbach@chromium.org // 29477e6132b924829c353864933f29124419916db550machenbach@chromium.org // We rewrite a for statement of the form 29487e6132b924829c353864933f29124419916db550machenbach@chromium.org // 29497e6132b924829c353864933f29124419916db550machenbach@chromium.org // for (let x = i; cond; next) body 29507e6132b924829c353864933f29124419916db550machenbach@chromium.org // 29517e6132b924829c353864933f29124419916db550machenbach@chromium.org // into 29527e6132b924829c353864933f29124419916db550machenbach@chromium.org // 29537e6132b924829c353864933f29124419916db550machenbach@chromium.org // { 29547e6132b924829c353864933f29124419916db550machenbach@chromium.org // let x = i; 29557e6132b924829c353864933f29124419916db550machenbach@chromium.org // temp_x = x; 29567e6132b924829c353864933f29124419916db550machenbach@chromium.org // flag = 1; 29577e6132b924829c353864933f29124419916db550machenbach@chromium.org // for (;;) { 29587e6132b924829c353864933f29124419916db550machenbach@chromium.org // let x = temp_x; 29597e6132b924829c353864933f29124419916db550machenbach@chromium.org // if (flag == 1) { 29607e6132b924829c353864933f29124419916db550machenbach@chromium.org // flag = 0; 29617e6132b924829c353864933f29124419916db550machenbach@chromium.org // } else { 29627e6132b924829c353864933f29124419916db550machenbach@chromium.org // next; 29637e6132b924829c353864933f29124419916db550machenbach@chromium.org // } 29647e6132b924829c353864933f29124419916db550machenbach@chromium.org // if (cond) { 29657e6132b924829c353864933f29124419916db550machenbach@chromium.org // <empty> 29667e6132b924829c353864933f29124419916db550machenbach@chromium.org // } else { 29677e6132b924829c353864933f29124419916db550machenbach@chromium.org // break; 29687e6132b924829c353864933f29124419916db550machenbach@chromium.org // } 29697e6132b924829c353864933f29124419916db550machenbach@chromium.org // b 29707e6132b924829c353864933f29124419916db550machenbach@chromium.org // temp_x = x; 29717e6132b924829c353864933f29124419916db550machenbach@chromium.org // } 29727e6132b924829c353864933f29124419916db550machenbach@chromium.org // } 29737e6132b924829c353864933f29124419916db550machenbach@chromium.org 2974e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(names->length() > 0); 29757e6132b924829c353864933f29124419916db550machenbach@chromium.org Scope* for_scope = scope_; 29767e6132b924829c353864933f29124419916db550machenbach@chromium.org ZoneList<Variable*> temps(names->length(), zone()); 29777e6132b924829c353864933f29124419916db550machenbach@chromium.org 29787e6132b924829c353864933f29124419916db550machenbach@chromium.org Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, 29797e6132b924829c353864933f29124419916db550machenbach@chromium.org RelocInfo::kNoPosition); 29807e6132b924829c353864933f29124419916db550machenbach@chromium.org outer_block->AddStatement(init, zone()); 29817e6132b924829c353864933f29124419916db550machenbach@chromium.org 29826313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org const AstRawString* temp_name = ast_value_factory()->dot_for_string(); 29837e6132b924829c353864933f29124419916db550machenbach@chromium.org 29847e6132b924829c353864933f29124419916db550machenbach@chromium.org // For each let variable x: 29857e6132b924829c353864933f29124419916db550machenbach@chromium.org // make statement: temp_x = x. 29867e6132b924829c353864933f29124419916db550machenbach@chromium.org for (int i = 0; i < names->length(); i++) { 29877e6132b924829c353864933f29124419916db550machenbach@chromium.org VariableProxy* proxy = 29887e6132b924829c353864933f29124419916db550machenbach@chromium.org NewUnresolved(names->at(i), LET, Interface::NewValue()); 29897e6132b924829c353864933f29124419916db550machenbach@chromium.org Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name); 29907e6132b924829c353864933f29124419916db550machenbach@chromium.org VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 29917e6132b924829c353864933f29124419916db550machenbach@chromium.org Assignment* assignment = factory()->NewAssignment( 29927e6132b924829c353864933f29124419916db550machenbach@chromium.org Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); 29937e6132b924829c353864933f29124419916db550machenbach@chromium.org Statement* assignment_statement = factory()->NewExpressionStatement( 29947e6132b924829c353864933f29124419916db550machenbach@chromium.org assignment, RelocInfo::kNoPosition); 29957e6132b924829c353864933f29124419916db550machenbach@chromium.org outer_block->AddStatement(assignment_statement, zone()); 29967e6132b924829c353864933f29124419916db550machenbach@chromium.org temps.Add(temp, zone()); 29977e6132b924829c353864933f29124419916db550machenbach@chromium.org } 29987e6132b924829c353864933f29124419916db550machenbach@chromium.org 29997e6132b924829c353864933f29124419916db550machenbach@chromium.org Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name); 30007e6132b924829c353864933f29124419916db550machenbach@chromium.org // Make statement: flag = 1. 30017e6132b924829c353864933f29124419916db550machenbach@chromium.org { 30027e6132b924829c353864933f29124419916db550machenbach@chromium.org VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 300308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 30047e6132b924829c353864933f29124419916db550machenbach@chromium.org Assignment* assignment = factory()->NewAssignment( 30057e6132b924829c353864933f29124419916db550machenbach@chromium.org Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); 30067e6132b924829c353864933f29124419916db550machenbach@chromium.org Statement* assignment_statement = factory()->NewExpressionStatement( 30077e6132b924829c353864933f29124419916db550machenbach@chromium.org assignment, RelocInfo::kNoPosition); 30087e6132b924829c353864933f29124419916db550machenbach@chromium.org outer_block->AddStatement(assignment_statement, zone()); 30097e6132b924829c353864933f29124419916db550machenbach@chromium.org } 30107e6132b924829c353864933f29124419916db550machenbach@chromium.org 30117e6132b924829c353864933f29124419916db550machenbach@chromium.org outer_block->AddStatement(loop, zone()); 30127e6132b924829c353864933f29124419916db550machenbach@chromium.org outer_block->set_scope(for_scope); 30137e6132b924829c353864933f29124419916db550machenbach@chromium.org scope_ = inner_scope; 30147e6132b924829c353864933f29124419916db550machenbach@chromium.org 30157e6132b924829c353864933f29124419916db550machenbach@chromium.org Block* inner_block = factory()->NewBlock(NULL, 2 * names->length() + 3, 30167e6132b924829c353864933f29124419916db550machenbach@chromium.org false, RelocInfo::kNoPosition); 30177e6132b924829c353864933f29124419916db550machenbach@chromium.org int pos = scanner()->location().beg_pos; 30187e6132b924829c353864933f29124419916db550machenbach@chromium.org ZoneList<Variable*> inner_vars(names->length(), zone()); 30197e6132b924829c353864933f29124419916db550machenbach@chromium.org 30207e6132b924829c353864933f29124419916db550machenbach@chromium.org // For each let variable x: 30217e6132b924829c353864933f29124419916db550machenbach@chromium.org // make statement: let x = temp_x. 30227e6132b924829c353864933f29124419916db550machenbach@chromium.org for (int i = 0; i < names->length(); i++) { 30237e6132b924829c353864933f29124419916db550machenbach@chromium.org VariableProxy* proxy = 30247e6132b924829c353864933f29124419916db550machenbach@chromium.org NewUnresolved(names->at(i), LET, Interface::NewValue()); 30257e6132b924829c353864933f29124419916db550machenbach@chromium.org Declaration* declaration = 30267e6132b924829c353864933f29124419916db550machenbach@chromium.org factory()->NewVariableDeclaration(proxy, LET, scope_, pos); 30277e6132b924829c353864933f29124419916db550machenbach@chromium.org Declare(declaration, true, CHECK_OK); 30287e6132b924829c353864933f29124419916db550machenbach@chromium.org inner_vars.Add(declaration->proxy()->var(), zone()); 30297e6132b924829c353864933f29124419916db550machenbach@chromium.org VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 30307e6132b924829c353864933f29124419916db550machenbach@chromium.org Assignment* assignment = factory()->NewAssignment( 30317e6132b924829c353864933f29124419916db550machenbach@chromium.org Token::INIT_LET, proxy, temp_proxy, pos); 30327e6132b924829c353864933f29124419916db550machenbach@chromium.org Statement* assignment_statement = factory()->NewExpressionStatement( 30337e6132b924829c353864933f29124419916db550machenbach@chromium.org assignment, pos); 30347e6132b924829c353864933f29124419916db550machenbach@chromium.org proxy->var()->set_initializer_position(pos); 30357e6132b924829c353864933f29124419916db550machenbach@chromium.org inner_block->AddStatement(assignment_statement, zone()); 30367e6132b924829c353864933f29124419916db550machenbach@chromium.org } 30377e6132b924829c353864933f29124419916db550machenbach@chromium.org 30387e6132b924829c353864933f29124419916db550machenbach@chromium.org // Make statement: if (flag == 1) { flag = 0; } else { next; }. 303912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org if (next) { 30407e6132b924829c353864933f29124419916db550machenbach@chromium.org Expression* compare = NULL; 30417e6132b924829c353864933f29124419916db550machenbach@chromium.org // Make compare expresion: flag == 1. 30427e6132b924829c353864933f29124419916db550machenbach@chromium.org { 304308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 30447e6132b924829c353864933f29124419916db550machenbach@chromium.org VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 30457e6132b924829c353864933f29124419916db550machenbach@chromium.org compare = factory()->NewCompareOperation( 30461e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Token::EQ, flag_proxy, const1, pos); 30477e6132b924829c353864933f29124419916db550machenbach@chromium.org } 30487e6132b924829c353864933f29124419916db550machenbach@chromium.org Statement* clear_flag = NULL; 30497e6132b924829c353864933f29124419916db550machenbach@chromium.org // Make statement: flag = 0. 30507e6132b924829c353864933f29124419916db550machenbach@chromium.org { 30517e6132b924829c353864933f29124419916db550machenbach@chromium.org VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 305208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); 30537e6132b924829c353864933f29124419916db550machenbach@chromium.org Assignment* assignment = factory()->NewAssignment( 30547e6132b924829c353864933f29124419916db550machenbach@chromium.org Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition); 30557e6132b924829c353864933f29124419916db550machenbach@chromium.org clear_flag = factory()->NewExpressionStatement(assignment, pos); 30567e6132b924829c353864933f29124419916db550machenbach@chromium.org } 30577e6132b924829c353864933f29124419916db550machenbach@chromium.org Statement* clear_flag_or_next = factory()->NewIfStatement( 30587e6132b924829c353864933f29124419916db550machenbach@chromium.org compare, clear_flag, next, RelocInfo::kNoPosition); 30597e6132b924829c353864933f29124419916db550machenbach@chromium.org inner_block->AddStatement(clear_flag_or_next, zone()); 30607e6132b924829c353864933f29124419916db550machenbach@chromium.org } 30617e6132b924829c353864933f29124419916db550machenbach@chromium.org 30627e6132b924829c353864933f29124419916db550machenbach@chromium.org 30637e6132b924829c353864933f29124419916db550machenbach@chromium.org // Make statement: if (cond) { } else { break; }. 306412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org if (cond) { 30657e6132b924829c353864933f29124419916db550machenbach@chromium.org Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 306608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org BreakableStatement* t = LookupBreakTarget(NULL, CHECK_OK); 30677e6132b924829c353864933f29124419916db550machenbach@chromium.org Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition); 30687e6132b924829c353864933f29124419916db550machenbach@chromium.org Statement* if_not_cond_break = factory()->NewIfStatement( 30691e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org cond, empty, stop, cond->position()); 30707e6132b924829c353864933f29124419916db550machenbach@chromium.org inner_block->AddStatement(if_not_cond_break, zone()); 30717e6132b924829c353864933f29124419916db550machenbach@chromium.org } 30727e6132b924829c353864933f29124419916db550machenbach@chromium.org 30737e6132b924829c353864933f29124419916db550machenbach@chromium.org inner_block->AddStatement(body, zone()); 30747e6132b924829c353864933f29124419916db550machenbach@chromium.org 30757e6132b924829c353864933f29124419916db550machenbach@chromium.org // For each let variable x: 30767e6132b924829c353864933f29124419916db550machenbach@chromium.org // make statement: temp_x = x; 30777e6132b924829c353864933f29124419916db550machenbach@chromium.org for (int i = 0; i < names->length(); i++) { 30787e6132b924829c353864933f29124419916db550machenbach@chromium.org VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 30797e6132b924829c353864933f29124419916db550machenbach@chromium.org int pos = scanner()->location().end_pos; 30807e6132b924829c353864933f29124419916db550machenbach@chromium.org VariableProxy* proxy = factory()->NewVariableProxy(inner_vars.at(i), pos); 30817e6132b924829c353864933f29124419916db550machenbach@chromium.org Assignment* assignment = factory()->NewAssignment( 30827e6132b924829c353864933f29124419916db550machenbach@chromium.org Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); 30837e6132b924829c353864933f29124419916db550machenbach@chromium.org Statement* assignment_statement = factory()->NewExpressionStatement( 30847e6132b924829c353864933f29124419916db550machenbach@chromium.org assignment, RelocInfo::kNoPosition); 30857e6132b924829c353864933f29124419916db550machenbach@chromium.org inner_block->AddStatement(assignment_statement, zone()); 30867e6132b924829c353864933f29124419916db550machenbach@chromium.org } 30877e6132b924829c353864933f29124419916db550machenbach@chromium.org 30887e6132b924829c353864933f29124419916db550machenbach@chromium.org inner_scope->set_end_position(scanner()->location().end_pos); 30897e6132b924829c353864933f29124419916db550machenbach@chromium.org inner_block->set_scope(inner_scope); 30907e6132b924829c353864933f29124419916db550machenbach@chromium.org scope_ = for_scope; 30917e6132b924829c353864933f29124419916db550machenbach@chromium.org 30927e6132b924829c353864933f29124419916db550machenbach@chromium.org loop->Initialize(NULL, NULL, NULL, inner_block); 30937e6132b924829c353864933f29124419916db550machenbach@chromium.org return outer_block; 30947e6132b924829c353864933f29124419916db550machenbach@chromium.org} 30957e6132b924829c353864933f29124419916db550machenbach@chromium.org 30967e6132b924829c353864933f29124419916db550machenbach@chromium.org 309708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 309808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool* ok) { 309943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ForStatement :: 310043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 310143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3102a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 310343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* init = NULL; 310408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ZoneList<const AstRawString*> let_bindings(1, zone()); 310543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3106394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Create an in-between scope for let-bound iteration variables. 3107f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* saved_scope = scope_; 3108f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); 3109f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_ = for_scope; 3110394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 311143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::FOR, CHECK_OK); 311243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 3113f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org for_scope->set_start_position(scanner()->location().beg_pos); 311443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::SEMICOLON) { 311543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::VAR || peek() == Token::CONST) { 311628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org bool is_const = peek() == Token::CONST; 311708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = NULL; 311841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org VariableDeclarationProperties decl_props = kHasNoInitializers; 311943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Block* variable_statement = 312041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, 312141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org CHECK_OK); 312241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org bool accept_OF = decl_props == kHasNoInitializers; 31231fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement::VisitMode mode; 31244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 312508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org if (name != NULL && CheckInOrOf(accept_OF, &mode)) { 312628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org Interface* interface = 312728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org is_const ? Interface::NewConst() : Interface::NewValue(); 3128a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ForEachStatement* loop = 3129a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewForEachStatement(mode, labels, pos); 3130e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 313143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 313243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* enumerable = ParseExpression(true, CHECK_OK); 313343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 313443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 313533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org VariableProxy* each = 3136f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_->NewUnresolved(factory(), name, interface); 313743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 31381fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org InitializeForEachStatement(loop, each, enumerable, body); 3139a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* result = 3140a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); 3141400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(variable_statement, zone()); 3142400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(loop, zone()); 3143f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_ = saved_scope; 3144f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org for_scope->set_end_position(scanner()->location().end_pos); 3145394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope = for_scope->FinalizeBlockScope(); 3146e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(for_scope == NULL); 3147fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // Parsed for-in loop w/ variable/const declaration. 3148fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org return result; 314943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 315043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen init = variable_statement; 315143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 315270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } else if (peek() == Token::LET && strict_mode() == STRICT) { 3153e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(allow_harmony_scoping()); 315408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = NULL; 3155394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com VariableDeclarationProperties decl_props = kHasNoInitializers; 3156394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Block* variable_statement = 315708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, 315808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org &name, CHECK_OK); 315908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool accept_IN = name != NULL && decl_props != kHasInitializers; 316041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org bool accept_OF = decl_props == kHasNoInitializers; 31611fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement::VisitMode mode; 31621fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 316341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (accept_IN && CheckInOrOf(accept_OF, &mode)) { 3164394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Rewrite a for-in statement of the form 3165394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 3166394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // for (let x in e) b 3167394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 3168394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // into 3169394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 3170394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // <let x' be a temporary variable> 3171394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // for (x' in e) { 3172394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // let x; 3173394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // x = x'; 3174394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // b; 3175394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // } 3176394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 3177394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // TODO(keuchel): Move the temporary variable to the block scope, after 3178394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // implementing stack allocated block scoped variables. 317908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Variable* temp = scope_->DeclarationScope()->NewTemporary( 31806313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->dot_for_string()); 3181b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 3182a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ForEachStatement* loop = 3183a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewForEachStatement(mode, labels, pos); 3184394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Target target(&this->target_stack_, loop); 3185394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 318633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // The expression does not see the loop variable. 3187f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_ = saved_scope; 3188394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Expression* enumerable = ParseExpression(true, CHECK_OK); 3189f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_ = for_scope; 3190394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Expect(Token::RPAREN, CHECK_OK); 319143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 319233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org VariableProxy* each = 3193f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_->NewUnresolved(factory(), name, Interface::NewValue()); 3194394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Statement* body = ParseStatement(NULL, CHECK_OK); 3195a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* body_block = 3196a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3197b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org Assignment* assignment = factory()->NewAssignment( 3198b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); 3199a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Statement* assignment_statement = factory()->NewExpressionStatement( 3200a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org assignment, RelocInfo::kNoPosition); 3201400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body_block->AddStatement(variable_statement, zone()); 3202400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body_block->AddStatement(assignment_statement, zone()); 3203400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body_block->AddStatement(body, zone()); 32041fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); 3205f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_ = saved_scope; 3206f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org for_scope->set_end_position(scanner()->location().end_pos); 3207394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope = for_scope->FinalizeBlockScope(); 3208ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com body_block->set_scope(for_scope); 3209394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Parsed for-in loop w/ let declaration. 3210394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return loop; 3211394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 3212394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 3213394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com init = variable_statement; 3214394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 321543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 32162904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Scanner::Location lhs_location = scanner()->peek_location(); 321743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expression = ParseExpression(false, CHECK_OK); 32181fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement::VisitMode mode; 321941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org bool accept_OF = expression->AsVariableProxy(); 32201fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 322141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (CheckInOrOf(accept_OF, &mode)) { 32224edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org expression = this->CheckAndRewriteReferenceExpression( 32234edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org expression, lhs_location, "invalid_lhs_in_for", CHECK_OK); 32244edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 3225a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ForEachStatement* loop = 3226a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewForEachStatement(mode, labels, pos); 3227e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 322843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 322943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* enumerable = ParseExpression(true, CHECK_OK); 323043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 323143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 323243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 32331fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org InitializeForEachStatement(loop, expression, enumerable, body); 3234f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_ = saved_scope; 3235f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org for_scope->set_end_position(scanner()->location().end_pos); 3236394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope = for_scope->FinalizeBlockScope(); 3237e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(for_scope == NULL); 323843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parsed for-in loop. 323943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return loop; 324043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 324143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 3242a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org init = factory()->NewExpressionStatement( 3243a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org expression, RelocInfo::kNoPosition); 324443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 324543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 324643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 324743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 324843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Standard 'for' loop 3249a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ForStatement* loop = factory()->NewForStatement(labels, pos); 3250e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 325143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 325243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parsed initializer at this point. 325343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SEMICOLON, CHECK_OK); 325443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32557e6132b924829c353864933f29124419916db550machenbach@chromium.org // If there are let bindings, then condition and the next statement of the 32567e6132b924829c353864933f29124419916db550machenbach@chromium.org // for loop must be parsed in a new scope. 32577e6132b924829c353864933f29124419916db550machenbach@chromium.org Scope* inner_scope = NULL; 32587e6132b924829c353864933f29124419916db550machenbach@chromium.org if (let_bindings.length() > 0) { 32597e6132b924829c353864933f29124419916db550machenbach@chromium.org inner_scope = NewScope(for_scope, BLOCK_SCOPE); 32607e6132b924829c353864933f29124419916db550machenbach@chromium.org inner_scope->set_start_position(scanner()->location().beg_pos); 32617e6132b924829c353864933f29124419916db550machenbach@chromium.org scope_ = inner_scope; 32627e6132b924829c353864933f29124419916db550machenbach@chromium.org } 32637e6132b924829c353864933f29124419916db550machenbach@chromium.org 326443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* cond = NULL; 326543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::SEMICOLON) { 326643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cond = ParseExpression(true, CHECK_OK); 326743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 326843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SEMICOLON, CHECK_OK); 326943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 327043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* next = NULL; 327143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::RPAREN) { 327243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* exp = ParseExpression(true, CHECK_OK); 3273a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition); 327443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 327543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 327643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 327743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 32787e6132b924829c353864933f29124419916db550machenbach@chromium.org 32797e6132b924829c353864933f29124419916db550machenbach@chromium.org Statement* result = NULL; 32807e6132b924829c353864933f29124419916db550machenbach@chromium.org if (let_bindings.length() > 0) { 32817e6132b924829c353864933f29124419916db550machenbach@chromium.org scope_ = for_scope; 32827e6132b924829c353864933f29124419916db550machenbach@chromium.org result = DesugarLetBindingsInForStatement(inner_scope, &let_bindings, loop, 32837e6132b924829c353864933f29124419916db550machenbach@chromium.org init, cond, next, body, CHECK_OK); 32847e6132b924829c353864933f29124419916db550machenbach@chromium.org scope_ = saved_scope; 32857e6132b924829c353864933f29124419916db550machenbach@chromium.org for_scope->set_end_position(scanner()->location().end_pos); 3286394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 32877e6132b924829c353864933f29124419916db550machenbach@chromium.org scope_ = saved_scope; 32887e6132b924829c353864933f29124419916db550machenbach@chromium.org for_scope->set_end_position(scanner()->location().end_pos); 328912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org for_scope = for_scope->FinalizeBlockScope(); 329012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org if (for_scope) { 329112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Rewrite a for statement of the form 329212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // for (const x = i; c; n) b 329312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // 329412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // into 329512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // 329612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // { 329712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // const x = i; 329812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // for (; c; n) b 329912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // } 3300e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(init != NULL); 330112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Block* block = 330212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); 330312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org block->AddStatement(init, zone()); 330412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org block->AddStatement(loop, zone()); 330512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org block->set_scope(for_scope); 330612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org loop->Initialize(NULL, cond, next, body); 330712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org result = block; 330812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } else { 330912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org loop->Initialize(init, cond, next, body); 331012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org result = loop; 331112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 3312394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 33137e6132b924829c353864933f29124419916db550machenbach@chromium.org return result; 331443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 331543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 331643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 331743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { 331843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 331943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // contexts this is used as a statement which invokes the debugger as i a 332043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // break point is present. 332143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // DebuggerStatement :: 332243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'debugger' ';' 332343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3324a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 332543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::DEBUGGER, CHECK_OK); 332643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 3327a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewDebuggerStatement(pos); 332843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 332943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 333043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3331bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgbool CompileTimeValue::IsCompileTimeValue(Expression* expression) { 3332196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (expression->IsLiteral()) return true; 3333bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org MaterializedLiteral* lit = expression->AsMaterializedLiteral(); 3334bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return lit != NULL && lit->is_simple(); 3335bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3336bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 33370b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 33383d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgHandle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, 33393d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Expression* expression) { 33403d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Factory* factory = isolate->factory(); 3341e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsCompileTimeValue(expression)); 3342d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Handle<FixedArray> result = factory->NewFixedArray(2, TENURED); 3343bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ObjectLiteral* object_literal = expression->AsObjectLiteral(); 3344bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org if (object_literal != NULL) { 3345e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(object_literal->is_simple()); 3346f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org if (object_literal->fast_elements()) { 3347dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS)); 3348f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } else { 3349dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS)); 3350f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } 3351bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org result->set(kElementsSlot, *object_literal->constant_properties()); 3352bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } else { 3353bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ArrayLiteral* array_literal = expression->AsArrayLiteral(); 3354e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(array_literal != NULL && array_literal->is_simple()); 3355dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL)); 33560c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org result->set(kElementsSlot, *array_literal->constant_elements()); 3357bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 3358bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return result; 3359bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3360bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3361bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3362dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgCompileTimeValue::LiteralType CompileTimeValue::GetLiteralType( 3363dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<FixedArray> value) { 3364dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); 3365dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org return static_cast<LiteralType>(literal_type->value()); 3366bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3367bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3368bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3369bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgHandle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { 3370bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); 3371bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3372bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3373bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 33749bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgbool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression, 33759bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Scope* scope, int* num_params, 33769bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Scanner::Location* dupe_loc) { 33779bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // Case for empty parameter lists: 33789bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // () => ... 33799bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (expression == NULL) return true; 33809bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 33819bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // Too many parentheses around expression: 33829bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // (( ... )) => ... 33839bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (expression->parenthesization_level() > 1) return false; 33849bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 33859bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // Case for a single parameter: 33869bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // (foo) => ... 33879bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // foo => ... 33889bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (expression->IsVariableProxy()) { 33899bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (expression->AsVariableProxy()->is_this()) return false; 33909bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 33919bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org const AstRawString* raw_name = expression->AsVariableProxy()->raw_name(); 33929bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (traits->IsEvalOrArguments(raw_name) || 33939bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org traits->IsFutureStrictReserved(raw_name)) 33949bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org return false; 33959bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 33969bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (scope->IsDeclared(raw_name)) { 33979bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org *dupe_loc = Scanner::Location( 33989bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org expression->position(), expression->position() + raw_name->length()); 33999bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org return false; 34009bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org } 34019bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 34029bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org scope->DeclareParameter(raw_name, VAR); 34039bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org ++(*num_params); 34049bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org return true; 34059bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org } 34069bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 34079bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // Case for more than one parameter: 34089bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // (foo, bar [, ...]) => ... 34099bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (expression->IsBinaryOperation()) { 34109bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org BinaryOperation* binop = expression->AsBinaryOperation(); 34119bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() || 34129bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org binop->right()->is_parenthesized()) 34139bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org return false; 34149bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 34159bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org return CheckAndDeclareArrowParameter(traits, binop->left(), scope, 34169bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org num_params, dupe_loc) && 34179bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org CheckAndDeclareArrowParameter(traits, binop->right(), scope, 34189bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org num_params, dupe_loc); 34199bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org } 34209bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 34219bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // Any other kind of expression is not a valid parameter list. 34229bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org return false; 34239bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org} 34249bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 34259bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 34269bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgint ParserTraits::DeclareArrowParametersFromExpression( 34279bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Expression* expression, Scope* scope, Scanner::Location* dupe_loc, 34289bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org bool* ok) { 34299bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org int num_params = 0; 34309bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params, 34319bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org dupe_loc); 34329bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org return num_params; 34339bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org} 34349bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 34359bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 3436dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgFunctionLiteral* Parser::ParseFunctionLiteral( 34372c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org const AstRawString* function_name, Scanner::Location function_name_location, 34382c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, 3439dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org FunctionLiteral::FunctionType function_type, 34402c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { 344143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Function :: 344243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '(' FormalParameterList? ')' '{' FunctionBody '}' 3443dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org // 3444dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org // Getter :: 3445dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org // '(' ')' '{' FunctionBody '}' 3446dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org // 3447dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org // Setter :: 3448dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org // '(' PropertySetParameterList ')' '{' FunctionBody '}' 344943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3450a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = function_token_pos == RelocInfo::kNoPosition 3451a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ? peek_position() : function_token_pos; 3452a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org 34532c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org bool is_generator = IsGeneratorFunction(kind); 34542c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 34557c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // Anonymous functions were passed either the empty symbol or a null 34567c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // handle as the function name. Remember if we were passed a non-empty 34577c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // handle to decide whether to invoke function name inference. 345808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool should_infer_name = function_name == NULL; 34597c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 34607c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // We want a non-null handle as the function name. 34617c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org if (should_infer_name) { 34626313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org function_name = ast_value_factory()->empty_string(); 346343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 346443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 346543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int num_parameters = 0; 3466b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // Function declarations are function scoped in normal mode, so they are 3467b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // hoisted. In harmony block scoping mode they are block scoped, so they 3468b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // are not hoisted. 34691e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // 34701e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // One tricky case are function declarations in a local sloppy-mode eval: 34711e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // their declaration is hoisted, but they still see the local scope. E.g., 34721e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // 34731e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // function() { 34741e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // var x = 0 34751e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // try { throw 1 } catch (x) { eval("function g() { return x }") } 34761e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // return g() 34771e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // } 34781e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // 34791e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // needs to return 1. To distinguish such cases, we need to detect 34801e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // (1) whether a function stems from a sloppy eval, and 34811e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // (2) whether it actually hoists across the eval. 34821e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Unfortunately, we do not represent sloppy eval scopes, so we do not have 34831e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // either information available directly, especially not when lazily compiling 34841e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // a function like 'g'. We hence rely on the following invariants: 34851e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // - (1) is the case iff the innermost scope of the deserialized scope chain 34861e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // under which we compile is _not_ a declaration scope. This holds because 34871e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // in all normal cases, function declarations are fully hoisted to a 34881e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // declaration scope and compiled relative to that. 34891e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // - (2) is the case iff the current declaration scope is still the original 34901e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // one relative to the deserialized scope chain. Otherwise we must be 34911e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // compiling a function in an inner declaration scope in the eval, e.g. a 34921e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // nested function, and hoisting works normally relative to that. 3493f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* declaration_scope = scope_->DeclarationScope(); 34941e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Scope* original_declaration_scope = original_scope_->DeclarationScope(); 3495dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Scope* scope = 3496486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org function_type == FunctionLiteral::DECLARATION && 3497a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org (!allow_harmony_scoping() || strict_mode() == SLOPPY) && 34981e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org (original_scope_ == original_declaration_scope || 34991e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org declaration_scope != original_declaration_scope) 35001e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org ? NewScope(declaration_scope, FUNCTION_SCOPE) 3501f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org : NewScope(scope_, FUNCTION_SCOPE); 350204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ZoneList<Statement*>* body = NULL; 35031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int materialized_literal_count = -1; 35041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int expected_property_count = -1; 350504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int handler_count = 0; 350656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org FunctionLiteral::ParameterFlag duplicate_parameters = 350756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org FunctionLiteral::kNoDuplicateParameters; 3508471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ 3509471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ? FunctionLiteral::kIsParenthesized 3510471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org : FunctionLiteral::kNotParenthesized; 3511b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org AstProperties ast_properties; 35122c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org BailoutReason dont_optimize_reason = kNoReason; 351343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse function body. 351408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org { 351508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org FunctionState function_state(&function_state_, &scope_, scope, zone(), 35166313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory(), 35176313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org info()->ast_node_id_gen()); 3518f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_->SetScopeName(function_name); 351943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3520e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (is_generator) { 3521e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // For generators, allocating variables in contexts is currently a win 3522e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // because it minimizes the work needed to suspend and resume an 3523e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // activation. 3524f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_->ForceContextAllocation(); 3525e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 3526e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Calling a generator returns a generator object. That object is stored 3527e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // in a temporary variable, a definition that is used by "yield" 3528f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // expressions. This also marks the FunctionState as a generator. 3529f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Variable* temp = scope_->DeclarationScope()->NewTemporary( 35306313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->dot_generator_object_string()); 3531e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org function_state.set_generator_object_variable(temp); 3532e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 3533e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 353443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // FormalParameterList :: 353543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '(' (Identifier)*[','] ')' 353643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 3537f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope->set_start_position(scanner()->location().beg_pos); 3538bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org 3539bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org // We don't yet know if the function will be strict, so we cannot yet 3540bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org // produce errors for parameter names or duplicates. However, we remember 3541bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org // the locations of these errors if they occur and produce the errors later. 3542bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org Scanner::Location eval_args_error_log = Scanner::Location::invalid(); 3543bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org Scanner::Location dupe_error_loc = Scanner::Location::invalid(); 35441c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Scanner::Location reserved_loc = Scanner::Location::invalid(); 35450a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 3546dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || 3547dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org (peek() == Token::RPAREN && 3548dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org arity_restriction != FunctionLiteral::SETTER_ARITY); 354943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!done) { 355004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool is_strict_reserved = false; 355108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* param_name = 35520cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 3553378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3554378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Store locations for possible future error reports. 3555bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { 3556f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org eval_args_error_log = scanner()->location(); 3557378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 355804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (!reserved_loc.IsValid() && is_strict_reserved) { 3559f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org reserved_loc = scanner()->location(); 356083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 3561f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { 3562bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; 3563f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org dupe_error_loc = scanner()->location(); 3564bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org } 3565378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 35667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Variable* var = scope_->DeclareParameter(param_name, VAR); 35678640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (scope->strict_mode() == SLOPPY) { 35688640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // TODO(sigurds) Mark every parameter as maybe assigned. This is a 35698640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // conservative approximation necessary to account for parameters 35708640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // that are assigned via the arguments array. 35718640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org var->set_maybe_assigned(); 35728640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 35737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3574fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org num_parameters++; 3575876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org if (num_parameters > Code::kMaxArguments) { 3576196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ReportMessage("too_many_parameters"); 3577d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com *ok = false; 3578d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com return NULL; 3579d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 3580dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org if (arity_restriction == FunctionLiteral::SETTER_ARITY) break; 358143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen done = (peek() == Token::RPAREN); 358243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!done) Expect(Token::COMMA, CHECK_OK); 358343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 358443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 358543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 358643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 358743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 358843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we have a named function expression, we add a local variable 358943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration to the body of the function with the name of the 359043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function and let it refer to the function itself (closure). 359143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // NOTE: We create a proxy and resolve it here so that in the 359243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // future we can change the AST to only refer to VariableProxies 359343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // instead of Variables and Proxis as is the case now. 359404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Variable* fvar = NULL; 3595486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; 3596dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org if (function_type == FunctionLiteral::NAMED_EXPRESSION) { 3597a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if (allow_harmony_scoping() && strict_mode() == STRICT) { 3598486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org fvar_init_op = Token::INIT_CONST; 3599486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } 3600a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org VariableMode fvar_mode = 360170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org allow_harmony_scoping() && strict_mode() == STRICT 360270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org ? CONST : CONST_LEGACY; 3603e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(function_name != NULL); 36047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org fvar = new (zone()) 36057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Variable(scope_, function_name, fvar_mode, true /* is valid LHS */, 36067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Variable::NORMAL, kCreatedInitialized, kNotAssigned, 36077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Interface::NewConst()); 3608ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableProxy* proxy = factory()->NewVariableProxy(fvar); 3609a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( 3610f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org proxy, fvar_mode, scope_, RelocInfo::kNoPosition); 3611f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_->DeclareFunctionVar(fvar_declaration); 361243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 361343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3614f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Determine if the function can be parsed lazily. Lazy parsing is different 3615f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // from lazy compilation; we need to parse more eagerly than we compile. 3616f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3617f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // We can only parse lazily if we also compile lazily. The heuristics for 3618f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // lazy compilation are: 36191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // - It must not have been prohibited by the caller to Parse (some callers 36201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // need a full AST). 36219c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org // - The outer scope must allow lazy compilation of inner functions. 36221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // - The function mustn't be a function expression with an open parenthesis 36231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // before; we consider that a hint that the function will be called 36241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // immediately, and it would be a waste of time to make it lazily 36251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // compiled. 36261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // These are all things we can know at this point, without looking at the 36271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // function itself. 3628f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3629f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // In addition, we need to distinguish between these cases: 3630f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // (function foo() { 3631f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // bar = function() { return 1; } 3632f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // })(); 3633f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // and 3634f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // (function foo() { 3635f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // var a = 1; 3636f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // bar = function() { return a; } 3637f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // })(); 3638f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3639f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Now foo will be parsed eagerly and compiled eagerly (optimization: assume 3640f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // parenthesis before the function means that it will be called 3641f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // immediately). The inner function *must* be parsed eagerly to resolve the 3642f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // possible reference to the variable in foo's scope. However, it's possible 3643f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // that it will be compiled lazily. 3644f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3645f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // To make this additional case work, both Parser and PreParser implement a 3646f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // logic where only top-level functions will be parsed lazily. 3647f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool is_lazily_parsed = (mode() == PARSE_LAZILY && 3648f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_->AllowsLazyCompilation() && 3649f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org !parenthesized_function_); 3650c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org parenthesized_function_ = false; // The bit was set for this function only. 365143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3652f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (is_lazily_parsed) { 3653e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org SkipLazyFunctionBody(function_name, &materialized_literal_count, 3654e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org &expected_property_count, CHECK_OK); 3655e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } else { 3656e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, 3657e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org is_generator, CHECK_OK); 3658c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org materialized_literal_count = function_state.materialized_literal_count(); 3659c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org expected_property_count = function_state.expected_property_count(); 366004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org handler_count = function_state.handler_count(); 366143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 366243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36634b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org // Validate strict mode. 36642c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Concise methods use StrictFormalParameters. 36652c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (strict_mode() == STRICT || IsConciseMethod(kind)) { 36664b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org CheckStrictFunctionNameAndParameters(function_name, 36674b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org name_is_strict_reserved, 36684b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org function_name_location, 36694b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org eval_args_error_log, 36704b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org dupe_error_loc, 36714b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org reserved_loc, 36724b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org CHECK_OK); 36732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 36742c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (strict_mode() == STRICT) { 3675394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com CheckOctalLiteral(scope->start_position(), 3676394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->end_position(), 3677394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com CHECK_OK); 36780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 3679b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org ast_properties = *factory()->visitor()->ast_properties(); 36802c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); 36810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 368212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org if (allow_harmony_scoping() && strict_mode() == STRICT) { 368312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org CheckConflictingVarDeclarations(scope, CHECK_OK); 368412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 36851805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 36861805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 36879d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 36886313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org function_name, ast_value_factory(), scope, body, 36899d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org materialized_literal_count, expected_property_count, handler_count, 36909d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org num_parameters, duplicate_parameters, function_type, 36919d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org FunctionLiteral::kIsFunction, parenthesized, kind, pos); 3692a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org function_literal->set_function_token_position(function_token_pos); 3693b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org function_literal->set_ast_properties(&ast_properties); 36942c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org function_literal->set_dont_optimize_reason(dont_optimize_reason); 36955d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org 36967c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 369744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return function_literal; 369843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 369943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 370043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 370108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgvoid Parser::SkipLazyFunctionBody(const AstRawString* function_name, 3702e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org int* materialized_literal_count, 3703e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org int* expected_property_count, 3704e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org bool* ok) { 3705e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org int function_block_pos = position(); 37064c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (compile_options() == ScriptCompiler::kConsumeParserCache) { 3707e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // If we have cached data, we use it to skip parsing the function body. The 3708e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // data contains the information we need to construct the lazy function. 3709e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org FunctionEntry entry = 371070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org cached_parse_data_->GetFunctionEntry(function_block_pos); 371170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // Check that cached data is valid. 371270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org CHECK(entry.is_valid()); 371370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // End position greater than end of stream is safe, and hard to check. 371470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org CHECK(entry.end_pos() > function_block_pos); 371570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org scanner()->SeekForward(entry.end_pos() - 1); 371670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 371770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org scope_->set_end_position(entry.end_pos()); 371870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org Expect(Token::RBRACE, ok); 371970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (!*ok) { 3720e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org return; 3721e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 372221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org total_preparse_skipped_ += scope_->end_position() - function_block_pos; 372370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org *materialized_literal_count = entry.literal_count(); 372470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org *expected_property_count = entry.property_count(); 372570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org scope_->SetStrictMode(entry.strict_mode()); 3726e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } else { 3727e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // With no cached data, we partially parse the function, without building an 3728e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // AST. This gathers the data needed to build a lazy function. 3729e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org SingletonLogger logger; 3730e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org PreParser::PreParseResult result = 3731e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org ParseLazyFunctionBodyWithPreParser(&logger); 3732e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org if (result == PreParser::kPreParseStackOverflow) { 3733e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // Propagate stack overflow. 3734e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org set_stack_overflow(); 3735e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org *ok = false; 3736e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org return; 3737e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 3738e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org if (logger.has_error()) { 3739e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org ParserTraits::ReportMessageAt( 3740e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org Scanner::Location(logger.start(), logger.end()), 3741285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org logger.message(), logger.argument_opt(), logger.is_reference_error()); 3742e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org *ok = false; 3743e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org return; 3744e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 3745e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org scope_->set_end_position(logger.end()); 3746e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org Expect(Token::RBRACE, ok); 3747e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org if (!*ok) { 3748e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org return; 3749e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 375021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org total_preparse_skipped_ += scope_->end_position() - function_block_pos; 3751e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org *materialized_literal_count = logger.literals(); 3752e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org *expected_property_count = logger.properties(); 3753e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org scope_->SetStrictMode(logger.strict_mode()); 37544c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (compile_options() == ScriptCompiler::kProduceParserCache) { 3755e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(log_); 3756e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // Position right after terminal '}'. 3757e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org int body_end = scanner()->location().end_pos; 3758e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org log_->LogFunction(function_block_pos, body_end, 3759e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org *materialized_literal_count, 3760e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org *expected_property_count, 3761e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org scope_->strict_mode()); 3762e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 3763e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 3764e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org} 3765e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 3766e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 3767e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgZoneList<Statement*>* Parser::ParseEagerFunctionBody( 376808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* function_name, int pos, Variable* fvar, 3769e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org Token::Value fvar_init_op, bool is_generator, bool* ok) { 3770e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // Everything inside an eagerly parsed function will be parsed eagerly 3771e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // (see comment above). 3772e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 3773e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); 3774e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org if (fvar != NULL) { 3775e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org VariableProxy* fproxy = scope_->NewUnresolved( 3776e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org factory(), function_name, Interface::NewConst()); 3777e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org fproxy->BindTo(fvar); 3778e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org body->Add(factory()->NewExpressionStatement( 3779e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org factory()->NewAssignment(fvar_init_op, 3780e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org fproxy, 3781e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org factory()->NewThisFunction(pos), 3782e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org RelocInfo::kNoPosition), 3783e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org RelocInfo::kNoPosition), zone()); 3784e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 3785e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 3786e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // For generators, allocate and yield an iterator on function entry. 3787e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org if (is_generator) { 3788e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org ZoneList<Expression*>* arguments = 3789e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org new(zone()) ZoneList<Expression*>(0, zone()); 3790e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org CallRuntime* allocation = factory()->NewCallRuntime( 37916313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->empty_string(), 37926313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), arguments, 37936313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org pos); 3794e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org VariableProxy* init_proxy = factory()->NewVariableProxy( 3795e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org function_state_->generator_object_variable()); 3796e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org Assignment* assignment = factory()->NewAssignment( 3797e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); 3798e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org VariableProxy* get_proxy = factory()->NewVariableProxy( 3799e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org function_state_->generator_object_variable()); 3800e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org Yield* yield = factory()->NewYield( 3801ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); 3802e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org body->Add(factory()->NewExpressionStatement( 3803e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org yield, RelocInfo::kNoPosition), zone()); 3804e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 3805e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 3806b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org ParseSourceElements(body, Token::RBRACE, false, false, NULL, CHECK_OK); 3807e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 3808e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org if (is_generator) { 3809e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org VariableProxy* get_proxy = factory()->NewVariableProxy( 3810e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org function_state_->generator_object_variable()); 381108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Expression* undefined = 381208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); 3813ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, 381408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org RelocInfo::kNoPosition); 3815e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org body->Add(factory()->NewExpressionStatement( 3816e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org yield, RelocInfo::kNoPosition), zone()); 3817e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 3818e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 3819e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org Expect(Token::RBRACE, CHECK_OK); 3820e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org scope_->set_end_position(scanner()->location().end_pos); 3821e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 3822e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org return body; 3823e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org} 3824e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 3825e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 3826e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgPreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( 38271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SingletonLogger* logger) { 382821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org // This function may be called on a background thread too; record only the 382921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org // main thread preparse times. 383021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org if (pre_parse_timer_ != NULL) { 383121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org pre_parse_timer_->Start(); 383221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org } 3833e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(Token::LBRACE, scanner()->current_token()); 38341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 38351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (reusable_preparser_ == NULL) { 383621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_); 3837e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); 3838e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_modules(allow_modules()); 3839e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); 3840e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_lazy(true); 38419bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions()); 3842ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org reusable_preparser_->set_allow_harmony_numeric_literals( 3843ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org allow_harmony_numeric_literals()); 38447dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org reusable_preparser_->set_allow_classes(allow_classes()); 38452c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org reusable_preparser_->set_allow_harmony_object_literals( 38462c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org allow_harmony_object_literals()); 38471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 3848a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org PreParser::PreParseResult result = 3849486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org reusable_preparser_->PreParseLazyFunction(strict_mode(), 3850f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org is_generator(), 38511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org logger); 385221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org if (pre_parse_timer_ != NULL) { 385321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org pre_parse_timer_->Stop(); 385421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org } 38551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return result; 38561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org} 38571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 38581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 385943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseV8Intrinsic(bool* ok) { 386043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // CallRuntime :: 386143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '%' Identifier Arguments 386243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3863a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 386443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::MOD, CHECK_OK); 38658297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org // Allow "eval" or "arguments" for backward compatibility. 386608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 386743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 3868d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 3869d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (extension_ != NULL) { 387043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The extension structures are only accessible while parsing the 387143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // very first time not when reparsing because of lazy compilation. 3872f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_->DeclarationScope()->ForceEagerCompilation(); 387343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 387443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 387508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const Runtime::Function* function = Runtime::FunctionForName(name->string()); 387643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3877d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Check for built-in IS_VAR macro. 3878d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (function != NULL && 3879d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->intrinsic_type == Runtime::RUNTIME && 3880d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->function_id == Runtime::kIS_VAR) { 3881d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // %IS_VAR(x) evaluates to x if x is a variable, 3882d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // leads to a parse error otherwise. Could be implemented as an 3883d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // inline function %_IS_VAR(x) to eliminate this special case. 3884d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { 3885d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com return args->at(0); 3886d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } else { 3887285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ReportMessage("not_isvar"); 3888d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com *ok = false; 388943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 389043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 389143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 389243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3893d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Check that the expected number of arguments are being passed. 3894d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (function != NULL && 3895d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->nargs != -1 && 3896d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->nargs != args->length()) { 3897285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ReportMessage("illegal_access"); 3898d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com *ok = false; 3899d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com return NULL; 3900de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org } 3901de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 3902de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org // Check that the function is defined if it's an inline runtime call. 390308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org if (function == NULL && name->FirstCharacter() == '_') { 3904285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ParserTraits::ReportMessage("not_defined", name); 3905de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org *ok = false; 3906de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org return NULL; 3907f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } 3908f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 3909d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // We have a valid intrinsics call or a call to a builtin. 3910a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewCallRuntime(name, function, args, pos); 391143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 391243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 391343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3914a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgLiteral* Parser::GetLiteralUndefined(int position) { 391508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org return factory()->NewUndefinedLiteral(position); 391643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 391743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 391843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 39191805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { 39201805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Declaration* decl = scope->CheckConflictingVarDeclarations(); 39211805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org if (decl != NULL) { 39221805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // In harmony mode we treat conflicting variable bindinds as early 39231805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // errors. See ES5 16 for a definition of early errors. 392408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name = decl->proxy()->raw_name(); 39251805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org int position = decl->proxy()->position(); 39261805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Scanner::Location location = position == RelocInfo::kNoPosition 39271805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org ? Scanner::Location::invalid() 39281805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org : Scanner::Location(position, position + 1); 3929285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org ParserTraits::ReportMessageAt(location, "var_redeclaration", name); 39301805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org *ok = false; 39311805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 39321805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org} 39331805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 39341805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 393543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 393643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Parser support 393743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 393843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 393908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgbool Parser::TargetStackContainsLabel(const AstRawString* label) { 3940b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != NULL; t = t->previous()) { 3941b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org BreakableStatement* stat = t->node()->AsBreakableStatement(); 394243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (stat != NULL && ContainsLabel(stat->labels(), label)) 394343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 394443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 394543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 394643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 394743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 394843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 394908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgBreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, 395008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool* ok) { 395108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool anonymous = label == NULL; 3952b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != NULL; t = t->previous()) { 3953b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org BreakableStatement* stat = t->node()->AsBreakableStatement(); 395443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (stat == NULL) continue; 395543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if ((anonymous && stat->is_target_for_anonymous()) || 395643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen (!anonymous && ContainsLabel(stat->labels(), label))) { 3957b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org RegisterTargetUse(stat->break_target(), t->previous()); 395843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return stat; 395943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 396043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 396143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 396243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 396343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 396443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 396508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgIterationStatement* Parser::LookupContinueTarget(const AstRawString* label, 396643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* ok) { 396708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org bool anonymous = label == NULL; 3968b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != NULL; t = t->previous()) { 3969b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org IterationStatement* stat = t->node()->AsIterationStatement(); 397043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (stat == NULL) continue; 397143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3972e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(stat->is_target_for_anonymous()); 397343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (anonymous || ContainsLabel(stat->labels(), label)) { 3974b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org RegisterTargetUse(stat->continue_target(), t->previous()); 397543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return stat; 397643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 397743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 397843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 397943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 398043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 398143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 398244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid Parser::RegisterTargetUse(Label* target, Target* stop) { 3983b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org // Register that a break target found at the given stop in the 39847be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org // target stack has been used from the top of the target stack. Add 39857be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org // the break target to any TargetCollectors passed on the stack. 3986b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != stop; t = t->previous()) { 3987b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org TargetCollector* collector = t->node()->AsTargetCollector(); 39887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (collector != NULL) collector->AddTarget(target, zone()); 398943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 399043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 399143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 399243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3993d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgvoid Parser::HandleSourceURLComments() { 3994d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org if (scanner_.source_url()->length() > 0) { 3995d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org Handle<String> source_url = scanner_.source_url()->Internalize(isolate()); 3996d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org info_->script()->set_source_url(*source_url); 3997d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org } 3998d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org if (scanner_.source_mapping_url()->length() > 0) { 3999d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org Handle<String> source_mapping_url = 4000d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org scanner_.source_mapping_url()->Internalize(isolate()); 4001d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org info_->script()->set_source_mapping_url(*source_mapping_url); 4002d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org } 4003d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org} 4004d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 4005d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 40066a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid Parser::ThrowPendingError() { 40076313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org DCHECK(ast_value_factory()->IsInternalized()); 40086a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org if (has_pending_error_) { 40096313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org MessageLocation location(script(), pending_error_location_.beg_pos, 40106a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org pending_error_location_.end_pos); 40116a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Factory* factory = isolate()->factory(); 40126a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org bool has_arg = 401308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; 40146a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); 401508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org if (pending_error_arg_ != NULL) { 401608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Handle<String> arg_string = pending_error_arg_->string(); 401708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org elements->set(0, *arg_string); 40186a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org } else if (pending_error_char_arg_ != NULL) { 40196a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Handle<String> arg_string = 40206a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) 40216a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org .ToHandleChecked(); 40226a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org elements->set(0, *arg_string); 40236a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org } 40246313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org isolate()->debug()->OnCompileError(script()); 4025248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org 40266a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Handle<JSArray> array = factory->NewJSArrayWithElements(elements); 4027ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org Handle<Object> error; 4028ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org MaybeHandle<Object> maybe_error = 4029ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org pending_error_is_reference_error_ 4030ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org ? factory->NewReferenceError(pending_error_message_, array) 4031ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org : factory->NewSyntaxError(pending_error_message_, array); 4032ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org if (maybe_error.ToHandle(&error)) isolate()->Throw(*error, &location); 40336a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org } 40346a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org} 40356a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org 40366a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org 403721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.orgvoid Parser::Internalize() { 403821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org // Internalize strings. 40396313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->Internalize(isolate()); 404021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org 404121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org // Error processing. 404221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org if (info()->function() == NULL) { 404321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org if (stack_overflow()) { 404421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org isolate()->StackOverflow(); 404521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org } else { 404621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org ThrowPendingError(); 404721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org } 404821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org } 404921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org 405021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org // Move statistics to Isolate. 40515de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 40525de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org ++feature) { 40535de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org for (int i = 0; i < use_counts_[feature]; ++i) { 40545de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature)); 40555de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org } 40565de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org } 405721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org isolate()->counters()->total_preparse_skipped()->Increment( 405821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org total_preparse_skipped_); 40595de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org} 40605de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org 40615de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org 4062b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// ---------------------------------------------------------------------------- 4063a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Regular expressions 4064a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4065a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4066a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpParser::RegExpParser(FlatStringReader* in, 4067a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Handle<String>* error, 40685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org bool multiline, 40695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Zone* zone) 40703d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org : isolate_(zone->isolate()), 40715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org zone_(zone), 4072ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org error_(error), 4073ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org captures_(NULL), 4074ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org in_(in), 4075ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org current_(kEndMarker), 4076ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org next_pos_(0), 4077ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org capture_count_(0), 4078ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org has_more_(true), 4079ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org multiline_(multiline), 4080ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org simple_(false), 4081ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org contains_anchor_(false), 4082ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org is_scanned_for_captures_(false), 4083ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org failed_(false) { 4084023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org Advance(); 4085a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4086a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4087a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4088a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::Next() { 4089a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (has_next()) { 4090a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return in()->Get(next_pos_); 4091a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4092a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return kEndMarker; 4093a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4094a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4095a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4096a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4097a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Advance() { 4098a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (next_pos_ < in()->length()) { 4099ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org StackLimitCheck check(isolate()); 4100a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (check.HasOverflowed()) { 4101ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ReportError(CStrVector(Isolate::kStackOverflowMessage)); 41025a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else if (zone()->excess_allocation()) { 4103a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ReportError(CStrVector("Regular expression too large")); 4104a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4105a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org current_ = in()->Get(next_pos_); 4106a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org next_pos_++; 4107a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4108a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4109a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org current_ = kEndMarker; 4110a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org has_more_ = false; 4111a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4112a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4113a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4114a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4115a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Reset(int pos) { 4116a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org next_pos_ = pos; 411753ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org has_more_ = (pos < in()->length()); 4118a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4119a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4120a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4121a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4122a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Advance(int dist) { 4123023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org next_pos_ += dist - 1; 4124023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org Advance(); 4125a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4126a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4127a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 412837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.combool RegExpParser::simple() { 412937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return simple_; 4130a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4131a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4132e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 4133a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ReportError(Vector<const char> message) { 4134a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org failed_ = true; 4135b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked(); 4136a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Zip to the end to make sure the no more input is read. 4137a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org current_ = kEndMarker; 4138a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org next_pos_ = in()->length(); 4139a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return NULL; 4140a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4141a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4142a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4143a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Pattern :: 4144a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Disjunction 4145a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParsePattern() { 4146a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpTree* result = ParseDisjunction(CHECK_FAILED); 4147e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!has_more()); 41487ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org // If the result of parsing is a literal string atom, and it has the 41497ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org // same length as the input, then the atom is identical to the input. 41507ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org if (result->IsAtom() && result->AsAtom()->length() == in()->length()) { 41517ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org simple_ = true; 41527ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org } 4153a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return result; 4154a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4155a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4156a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4157a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Disjunction :: 4158a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Alternative 4159a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Alternative | Disjunction 4160a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Alternative :: 4161a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// [empty] 4162a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Term Alternative 4163a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Term :: 4164a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Assertion 4165a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Atom 4166a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Atom Quantifier 4167a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParseDisjunction() { 416886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Used to store current state while parsing subexpressions. 4169400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org RegExpParserState initial_state(NULL, INITIAL, 0, zone()); 417086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpParserState* stored_state = &initial_state; 417186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Cache the builder in a local variable for quick access. 417286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpBuilder* builder = initial_state.builder(); 4173a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (true) { 4174a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (current()) { 4175a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case kEndMarker: 417686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (stored_state->IsSubexpression()) { 417786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Inside a parenthesized group when hitting end of input. 417886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Unterminated group") CHECK_FAILED); 417986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 4180e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(INITIAL, stored_state->group_type()); 418186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Parsing completed successfully. 418286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org return builder->ToRegExp(); 418386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case ')': { 418486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (!stored_state->IsSubexpression()) { 418586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Unmatched ')'") CHECK_FAILED); 418686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 4187e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_NE(INITIAL, stored_state->group_type()); 418886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 4189a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 419086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // End disjunction parsing and convert builder content to new single 419186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // regexp atom. 419286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpTree* body = builder->ToRegExp(); 419386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 419486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org int end_capture_index = captures_started(); 419586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 419686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org int capture_index = stored_state->capture_index(); 4197dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org SubexpressionType group_type = stored_state->group_type(); 419886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 419986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Restore previous state. 420086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org stored_state = stored_state->previous_state(); 420186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder = stored_state->builder(); 420286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 420386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Build result of subexpression. 4204dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org if (group_type == CAPTURE) { 4205c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index); 420686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org captures_->at(capture_index - 1) = capture; 420786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org body = capture; 4208dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org } else if (group_type != GROUPING) { 4209e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(group_type == POSITIVE_LOOKAHEAD || 4210dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org group_type == NEGATIVE_LOOKAHEAD); 4211dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org bool is_positive = (group_type == POSITIVE_LOOKAHEAD); 4212c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org body = new(zone()) RegExpLookahead(body, 421386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org is_positive, 421486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org end_capture_index - capture_index, 421586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org capture_index); 4216a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 421786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(body); 421849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // For compatability with JSC and ES3, we allow quantifiers after 421949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // lookaheads, and break in all cases. 422086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 422186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 422286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case '|': { 422386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Advance(); 422486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->NewAlternative(); 4225a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 4226a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4227a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '*': 4228a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '+': 4229a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '?': 4230e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return ReportError(CStrVector("Nothing to repeat")); 4231a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '^': { 4232a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4233245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (multiline_) { 423486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 4235c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE)); 4236245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } else { 423786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 4238c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT)); 4239245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org set_contains_anchor(); 4240245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 4241a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 4242a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4243a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '$': { 4244a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4245dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org RegExpAssertion::AssertionType assertion_type = 4246a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org multiline_ ? RegExpAssertion::END_OF_LINE : 4247a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpAssertion::END_OF_INPUT; 4248dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type)); 4249a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 4250a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4251a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '.': { 4252a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4253a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // everything except \x0a, \x0d, \u2028 and \u2029 425440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org ZoneList<CharacterRange>* ranges = 42557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<CharacterRange>(2, zone()); 42567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange::AddClassEscape('.', ranges, zone()); 4257c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); 425886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 4259a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4260a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4261a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '(': { 4262dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org SubexpressionType subexpr_type = CAPTURE; 426386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Advance(); 426486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (current() == '?') { 426586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org switch (Next()) { 426686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case ':': 4267dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org subexpr_type = GROUPING; 426886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 426986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case '=': 4270dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org subexpr_type = POSITIVE_LOOKAHEAD; 427186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 427286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case '!': 4273dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org subexpr_type = NEGATIVE_LOOKAHEAD; 427486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 427586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org default: 427686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Invalid group") CHECK_FAILED); 427786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 427886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 427986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Advance(2); 428086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } else { 428186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (captures_ == NULL) { 42827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone()); 428386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 428486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (captures_started() >= kMaxCaptures) { 428586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Too many captures") CHECK_FAILED); 428686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 42877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org captures_->Add(NULL, zone()); 428886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 428986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Store current state and begin new disjunction parsing. 4290dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type, 4291400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org captures_started(), zone()); 429286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder = stored_state->builder(); 429349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org continue; 4294a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4295a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '[': { 4296a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpTree* atom = ParseCharacterClass(CHECK_FAILED); 429786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 4298a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4299a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4300a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Atom :: 4301a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // \ AtomEscape 4302a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '\\': 4303a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (Next()) { 4304a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case kEndMarker: 4305e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return ReportError(CStrVector("\\ at end of pattern")); 4306a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'b': 4307a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 430886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 4309c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY)); 4310a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 4311a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'B': 4312a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 431386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 4314c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY)); 4315a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 431649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // AtomEscape :: 431749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // CharacterClassEscape 431849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // 431949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // CharacterClassEscape :: one of 432049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // d D s S w W 4321a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'd': case 'D': case 's': case 'S': case 'w': case 'W': { 4322a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = Next(); 4323a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 432440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org ZoneList<CharacterRange>* ranges = 43257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<CharacterRange>(2, zone()); 43267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange::AddClassEscape(c, ranges, zone()); 4327c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); 432886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 432986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 4330a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4331a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '1': case '2': case '3': case '4': case '5': case '6': 4332a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '7': case '8': case '9': { 4333a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int index = 0; 4334a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseBackReferenceIndex(&index)) { 433586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpCapture* capture = NULL; 433686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (captures_ != NULL && index <= captures_->length()) { 433786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org capture = captures_->at(index - 1); 433886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 433986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (capture == NULL) { 434086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddEmpty(); 434186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 4342a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4343c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpTree* atom = new(zone()) RegExpBackReference(capture); 434486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 434586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 4346a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4347a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 first_digit = Next(); 4348a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (first_digit == '8' || first_digit == '9') { 4349a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Treat as identity escape 435086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(first_digit); 4351a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 4352a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4353a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4354a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4355a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // FALLTHROUGH 4356a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '0': { 4357a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4358a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 octal = ParseOctalLiteral(); 435986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(octal); 4360a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4361a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4362a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // ControlEscape :: one of 4363a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // f n r t v 4364a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'f': 4365a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 436686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\f'); 4367a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4368a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'n': 4369a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 437086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\n'); 4371a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4372a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'r': 4373a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 437486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\r'); 4375a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4376a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 't': 4377a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 437886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\t'); 4379a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4380a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'v': 4381a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 438286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\v'); 4383a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4384a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'c': { 4385d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Advance(); 4386d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 controlLetter = Next(); 4387d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Special case if it is an ASCII letter. 4388d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Convert lower case letters to uppercase. 4389d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 letter = controlLetter & ~('a' ^ 'A'); 4390d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if (letter < 'A' || 'Z' < letter) { 4391d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // controlLetter is not in range 'A'-'Z' or 'a'-'z'. 4392d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // This is outside the specification. We match JSC in 4393d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // reading the backslash as a literal character instead 4394d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // of as starting an escape. 4395d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org builder->AddCharacter('\\'); 4396d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } else { 4397d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Advance(2); 4398d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org builder->AddCharacter(controlLetter & 0x1f); 4399d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 4400a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4401a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4402a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'x': { 4403a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 4404a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 4405a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(2, &value)) { 440686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(value); 4407a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 440886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('x'); 4409a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4410a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4411a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4412a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'u': { 4413a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 4414a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 4415a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(4, &value)) { 441686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(value); 4417a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 441886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('u'); 4419a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4420a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4421a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4422a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 4423a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Identity escape. 442486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(Next()); 4425a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 4426a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4427a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4428a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4429a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '{': { 4430a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int dummy; 4431a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseIntervalQuantifier(&dummy, &dummy)) { 4432a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ReportError(CStrVector("Nothing to repeat") CHECK_FAILED); 4433a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4434a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // fallthrough 4435a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4436a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 443786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(current()); 4438a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4439a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4440a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } // end switch(current()) 4441a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4442a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int min; 4443a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int max; 4444a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (current()) { 4445a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // QuantifierPrefix :: 4446a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // * 4447a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // + 4448a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // ? 4449a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // { 4450a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '*': 4451a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org min = 0; 445237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com max = RegExpTree::kInfinity; 4453a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4454a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4455a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '+': 4456a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org min = 1; 445737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com max = RegExpTree::kInfinity; 4458a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4459a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4460a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '?': 4461a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org min = 0; 4462a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org max = 1; 4463a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4464a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4465a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '{': 4466a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseIntervalQuantifier(&min, &max)) { 4467245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (max < min) { 4468245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org ReportError(CStrVector("numbers out of order in {} quantifier.") 4469245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org CHECK_FAILED); 4470245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 4471a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4472a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4473a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 4474a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4475a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 4476a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 4477a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4478dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY; 4479a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '?') { 4480dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org quantifier_type = RegExpQuantifier::NON_GREEDY; 44810c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Advance(); 44820c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } else if (FLAG_regexp_possessive_quantifier && current() == '+') { 44830c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // FLAG_regexp_possessive_quantifier is a debug-only flag. 4484dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org quantifier_type = RegExpQuantifier::POSSESSIVE; 4485a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4486a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4487dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org builder->AddQuantifierToAtom(min, max, quantifier_type); 4488a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4489a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4490a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4491a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4492a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifdef DEBUG 4493e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org// Currently only used in an DCHECK. 4494a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatic bool IsSpecialClassEscape(uc32 c) { 4495a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (c) { 4496a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'd': case 'D': 4497a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 's': case 'S': 4498a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'w': case 'W': 4499a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 4500a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 4501a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 4502a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4503a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4504a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif 4505a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4506a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4507a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// In order to know whether an escape is a backreference or not we have to scan 4508a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// the entire regexp and find the number of capturing parentheses. However we 4509a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// don't want to scan the regexp twice unless it is necessary. This mini-parser 4510a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// is called when needed. It can see the difference between capturing and 4511a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// noncapturing parentheses and can skip character classes and backslash-escaped 4512a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// characters. 4513a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::ScanForCaptures() { 4514a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Start with captures started previous to current position 4515a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int capture_count = captures_started(); 4516a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Add count of captures after this position. 4517a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int n; 4518a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while ((n = current()) != kEndMarker) { 4519a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4520a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (n) { 4521a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '\\': 4522a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4523a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4524a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '[': { 4525a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int c; 4526a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while ((c = current()) != kEndMarker) { 4527a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4528a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (c == '\\') { 4529a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4530a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4531a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (c == ']') break; 4532a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4533a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4534a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4535a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4536a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '(': 4537a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() != '?') capture_count++; 4538a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4539a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4540a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4541a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org capture_count_ = capture_count; 4542a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org is_scanned_for_captures_ = true; 4543a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4544a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4545a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4546a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseBackReferenceIndex(int* index_out) { 4547e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ('\\', current()); 4548e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK('1' <= Next() && Next() <= '9'); 4549245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // Try to parse a decimal literal that is no greater than the total number 4550245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // of left capturing parentheses in the input. 4551a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int start = position(); 4552a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int value = Next() - '0'; 4553a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 4554a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (true) { 4555a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = current(); 4556a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (IsDecimalDigit(c)) { 4557a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org value = 10 * value + (c - '0'); 4558245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (value > kMaxCaptures) { 4559245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org Reset(start); 4560245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org return false; 4561245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 4562a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4563a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4564a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4565a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4566a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4567a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (value > captures_started()) { 4568a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!is_scanned_for_captures_) { 4569a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int saved_position = position(); 4570a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ScanForCaptures(); 4571a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(saved_position); 4572a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4573a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (value > capture_count_) { 4574a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 4575a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 4576a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4577a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4578a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *index_out = value; 4579a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 4580a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4581a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4582a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4583a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// QuantifierPrefix :: 4584a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// { DecimalDigits } 4585a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// { DecimalDigits , } 4586a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// { DecimalDigits , DecimalDigits } 4587245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// 4588245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// Returns true if parsing succeeds, and set the min_out and max_out 4589245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// values. Values are truncated to RegExpTree::kInfinity if they overflow. 4590a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) { 4591e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(current(), '{'); 4592a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int start = position(); 4593a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4594a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int min = 0; 4595a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!IsDecimalDigit(current())) { 4596a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 4597a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 4598a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4599a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (IsDecimalDigit(current())) { 4600245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org int next = current() - '0'; 4601245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (min > (RegExpTree::kInfinity - next) / 10) { 4602245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // Overflow. Skip past remaining decimal digits and return -1. 4603245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org do { 4604245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org Advance(); 4605245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } while (IsDecimalDigit(current())); 4606245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org min = RegExpTree::kInfinity; 4607245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org break; 4608245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 4609245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org min = 10 * min + next; 4610a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4611a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4612a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int max = 0; 4613a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '}') { 4614a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org max = min; 4615a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4616a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (current() == ',') { 4617a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4618a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '}') { 461937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com max = RegExpTree::kInfinity; 4620a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4621a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4622a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (IsDecimalDigit(current())) { 4623245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org int next = current() - '0'; 4624245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (max > (RegExpTree::kInfinity - next) / 10) { 4625245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org do { 4626245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org Advance(); 4627245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } while (IsDecimalDigit(current())); 4628245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org max = RegExpTree::kInfinity; 4629245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org break; 4630245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 4631245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org max = 10 * max + next; 4632a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4633a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4634a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() != '}') { 4635a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 4636a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 4637a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4638a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4639a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4640a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4641a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 4642a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 4643a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4644a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *min_out = min; 4645a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *max_out = max; 4646a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 4647a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4648a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4649a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4650a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::ParseOctalLiteral() { 4651e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker); 4652a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // For compatibility with some other browsers (not all), we parse 4653a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // up to three octal digits with a value below 256. 4654a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value = current() - '0'; 4655a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4656a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if ('0' <= current() && current() <= '7') { 4657a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org value = value * 8 + current() - '0'; 4658a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4659a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (value < 32 && '0' <= current() && current() <= '7') { 4660a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org value = value * 8 + current() - '0'; 4661a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4662a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4663a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4664a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return value; 4665a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4666a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4667a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4668a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseHexEscape(int length, uc32 *value) { 4669a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int start = position(); 4670a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 val = 0; 4671a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org bool done = false; 4672a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org for (int i = 0; !done; i++) { 4673a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = current(); 4674a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int d = HexValue(c); 4675a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (d < 0) { 4676a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 4677a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 4678a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4679a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org val = val * 16 + d; 4680a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4681a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (i == length - 1) { 4682a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org done = true; 4683a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4684a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4685a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *value = val; 4686a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 4687a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4688a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4689a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4690a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::ParseClassCharacterEscape() { 4691e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(current() == '\\'); 4692e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(has_next() && !IsSpecialClassEscape(Next())); 4693a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4694a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (current()) { 4695a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'b': 4696a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4697a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\b'; 4698a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // ControlEscape :: one of 4699a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // f n r t v 4700a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'f': 4701a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4702a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\f'; 4703a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'n': 4704a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4705a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\n'; 4706a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'r': 4707a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4708a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\r'; 4709a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 't': 4710a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4711a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\t'; 4712a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'v': 4713a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4714a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\v'; 4715d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org case 'c': { 4716d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 controlLetter = Next(); 4717d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 letter = controlLetter & ~('A' ^ 'a'); 4718d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // For compatibility with JSC, inside a character class 4719d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // we also accept digits and underscore as control characters. 4720d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if ((controlLetter >= '0' && controlLetter <= '9') || 4721d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org controlLetter == '_' || 4722d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org (letter >= 'A' && letter <= 'Z')) { 4723d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Advance(2); 4724d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Control letters mapped to ASCII control characters in the range 4725d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // 0x00-0x1f. 4726d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org return controlLetter & 0x1f; 4727d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 4728d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // We match JSC in reading the backslash as a literal 4729d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // character instead of as starting an escape. 4730d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org return '\\'; 4731d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 4732a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '0': case '1': case '2': case '3': case '4': case '5': 4733a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '6': case '7': 4734a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // For compatibility, we interpret a decimal escape that isn't 4735a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // a back reference (and therefore either \0 or not valid according 4736a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // to the specification) as a 1..3 digit octal character code. 4737a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return ParseOctalLiteral(); 4738a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'x': { 4739a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4740a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 4741a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(2, &value)) { 4742a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return value; 4743a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4744a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // If \x is not followed by a two-digit hexadecimal, treat it 4745a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // as an identity escape. 4746a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return 'x'; 4747a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4748a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'u': { 4749a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4750a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 4751a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(4, &value)) { 4752a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return value; 4753a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4754a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // If \u is not followed by a four-digit hexadecimal, treat it 4755a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // as an identity escape. 4756a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return 'u'; 4757a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4758a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: { 4759a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Extended identity escape. We accept any character that hasn't 4760a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // been matched by a more specific case, not just the subset required 4761a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // by the ECMAScript specification. 4762a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 result = current(); 4763a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4764a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return result; 4765a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4766a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4767a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return 0; 4768a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4769a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4770a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4771a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgCharacterRange RegExpParser::ParseClassAtom(uc16* char_class) { 4772e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0, *char_class); 4773a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 first = current(); 4774a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (first == '\\') { 4775a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (Next()) { 4776a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'w': case 'W': case 'd': case 'D': case 's': case 'S': { 4777a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *char_class = Next(); 4778a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 4779a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return CharacterRange::Singleton(0); // Return dummy value. 4780a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 478137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com case kEndMarker: 4782e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return ReportError(CStrVector("\\ at end of pattern")); 4783a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 4784a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = ParseClassCharacterEscape(CHECK_FAILED); 4785a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return CharacterRange::Singleton(c); 4786a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4787a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4788a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4789a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return CharacterRange::Singleton(first); 4790a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4791a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4792a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4793a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 479414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.orgstatic const uc16 kNoCharClass = 0; 479514a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org 479614a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// Adds range or pre-defined character class to character ranges. 479714a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// If char_class is not kInvalidClass, it's interpreted as a class 479814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// escape (i.e., 's' means whitespace, from '\s'). 479914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.orgstatic inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges, 480014a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org uc16 char_class, 48017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange range, 48027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Zone* zone) { 480314a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org if (char_class != kNoCharClass) { 48047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange::AddClassEscape(char_class, ranges, zone); 480514a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org } else { 48067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(range, zone); 480714a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org } 480814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org} 480914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org 481014a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org 4811a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParseCharacterClass() { 4812a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org static const char* kUnterminated = "Unterminated character class"; 4813a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org static const char* kRangeOutOfOrder = "Range out of order in character class"; 4814a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4815e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(current(), '['); 4816a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4817a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org bool is_negated = false; 4818a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '^') { 4819a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org is_negated = true; 4820a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4821a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 48227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<CharacterRange>* ranges = 48237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<CharacterRange>(2, zone()); 4824a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (has_more() && current() != ']') { 482514a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org uc16 char_class = kNoCharClass; 4826a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED); 4827a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '-') { 4828a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4829a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == kEndMarker) { 4830a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // If we reach the end we break out of the loop and let the 4831a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // following code report an error. 4832a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4833a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (current() == ']') { 48347028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class, first, zone()); 48357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Singleton('-'), zone()); 4836a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4837a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 483814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org uc16 char_class_2 = kNoCharClass; 483914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED); 484014a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org if (char_class != kNoCharClass || char_class_2 != kNoCharClass) { 484114a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org // Either end is an escaped character class. Treat the '-' verbatim. 48427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class, first, zone()); 48437028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Singleton('-'), zone()); 48447028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class_2, next, zone()); 484514a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org continue; 4846a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4847a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (first.from() > next.to()) { 4848a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED); 4849a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 48507028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Range(first.from(), next.to()), zone()); 4851a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 48527028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class, first, zone()); 4853a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4854a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4855a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!has_more()) { 4856a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return ReportError(CStrVector(kUnterminated) CHECK_FAILED); 4857a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4858a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4859a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ranges->length() == 0) { 48607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Everything(), zone()); 4861a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org is_negated = !is_negated; 4862a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4863c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org return new(zone()) RegExpCharacterClass(ranges, is_negated); 4864a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4865a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4866a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4867a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// ---------------------------------------------------------------------------- 486843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The Parser interface. 486943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4870e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgbool RegExpParser::ParseRegExp(FlatStringReader* input, 4871e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org bool multiline, 48725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org RegExpCompileData* result, 48735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Zone* zone) { 4874e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result != NULL); 48755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org RegExpParser parser(input, &result->error, multiline, zone); 487637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com RegExpTree* tree = parser.ParsePattern(); 4877a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (parser.failed()) { 4878e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(tree == NULL); 4879e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!result->error.is_null()); 4880a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4881e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(tree != NULL); 4882e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result->error.is_null()); 488337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result->tree = tree; 488437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com int capture_count = parser.captures_started(); 488537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; 4886245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org result->contains_anchor = parser.contains_anchor(); 488737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result->capture_count = capture_count; 4888a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4889a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return !parser.failed(); 4890a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4891a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4892a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4893e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool Parser::Parse() { 4894e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->function() == NULL); 4895b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org FunctionLiteral* result = NULL; 489621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org pre_parse_timer_ = isolate()->counters()->pre_parse(); 489742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org if (FLAG_trace_parse || allow_natives_syntax() || extension_ != NULL) { 489808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org // If intrinsics are allowed, the Parser cannot operate independent of the 489921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org // V8 heap because of Runtime. Tell the string table to internalize strings 490008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org // and values right after they're created. 49016313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ast_value_factory()->Internalize(isolate()); 490208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org } 490308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org 4904e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (info()->is_lazy()) { 4905e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->is_eval()); 4906e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (info()->shared_info()->is_function()) { 4907e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org result = ParseLazy(); 490856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org } else { 4909e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org result = ParseProgram(); 491056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org } 4911b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 491270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org SetCachedData(); 4913f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org result = ParseProgram(); 4914b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4915e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org info()->SetFunction(result); 491621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org 491721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org Internalize(); 49186313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org DCHECK(ast_value_factory()->IsInternalized()); 4919b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org return (result != NULL); 492043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 492143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4922b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 4923b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgvoid Parser::ParseOnBackground() { 4924b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org DCHECK(info()->function() == NULL); 4925b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org FunctionLiteral* result = NULL; 4926b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 4927b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 4928b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org CompleteParserRecorder recorder; 4929b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org if (compile_options() == ScriptCompiler::kProduceParserCache) { 4930b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org log_ = &recorder; 4931b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org } 4932b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 4933b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org DCHECK(info()->source_stream() != NULL); 4934b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org ExternalStreamingStream stream(info()->source_stream(), 4935b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org info()->source_stream_encoding()); 4936b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org scanner_.Initialize(&stream); 4937b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org DCHECK(info()->context().is_null() || info()->context()->IsNativeContext()); 4938b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 4939b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // When streaming, we don't know the length of the source until we have parsed 4940b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // it. The raw data can be UTF-8, so we wouldn't know the source length until 4941b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // we have decoded it anyway even if we knew the raw data length (which we 4942b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // don't). We work around this by storing all the scopes which need their end 4943b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // position set at the end of the script (the top scope and possible eval 4944b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // scopes) and set their end position after we know the script length. 4945b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Scope* top_scope = NULL; 4946b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Scope* eval_scope = NULL; 4947b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org result = DoParseProgram(info(), &top_scope, &eval_scope); 4948b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 4949b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org top_scope->set_end_position(scanner()->location().end_pos); 4950b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org if (eval_scope != NULL) { 4951b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org eval_scope->set_end_position(scanner()->location().end_pos); 4952b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org } 4953b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 4954b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org info()->SetFunction(result); 4955b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 4956b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // We cannot internalize on a background thread; a foreground task will take 4957b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // care of calling Parser::Internalize just before compilation. 4958b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 4959b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org if (compile_options() == ScriptCompiler::kProduceParserCache) { 4960b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); 4961b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org log_ = NULL; 4962b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org } 4963b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org} 496443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 4965