1fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met: 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions of source code must retain the above copyright 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer. 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions in binary form must reproduce the above 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// copyright notice, this list of conditions and the following 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// disclaimer in the documentation and/or other materials provided 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with the distribution. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Neither the name of Google Inc. nor the names of its 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contributors may be used to endorse or promote products derived 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from this software without specific prior written permission. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h" 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "api.h" 31c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org#include "ast.h" 3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "bootstrapper.h" 331805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org#include "char-predicates-inl.h" 34f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org#include "codegen.h" 35b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org#include "compiler.h" 3665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "func-name-inferrer.h" 37ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#include "messages.h" 38dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org#include "parser.h" 3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "platform.h" 40fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org#include "preparser.h" 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "runtime.h" 4255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org#include "scanner-character-streams.h" 43b5737496145078e47f3d28f19ed8d918e2254738ager@chromium.org#include "scopeinfo.h" 44a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "string-stream.h" 4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 4771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 4843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 49b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org// PositionStack is used for on-stack allocation of token positions for 50b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org// new expressions. Please look at ParseNewExpression. 51b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 52b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgclass PositionStack { 53b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org public: 54b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {} 55068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org ~PositionStack() { 56068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org ASSERT(!*ok_ || is_empty()); 57068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org USE(ok_); 58068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } 59b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 60b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org class Element { 61b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org public: 62b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Element(PositionStack* stack, int value) { 63b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org previous_ = stack->top(); 64b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org value_ = value; 65b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org stack->set_top(this); 66b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org } 67b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 68b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org private: 69b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Element* previous() { return previous_; } 70b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org int value() { return value_; } 71b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org friend class PositionStack; 72b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Element* previous_; 73b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org int value_; 74b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org }; 75b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 76b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org bool is_empty() { return top_ == NULL; } 77b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org int pop() { 78b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org ASSERT(!is_empty()); 79b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org int result = top_->value(); 80b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org top_ = top_->previous(); 81b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org return result; 82b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org } 83b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 84b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org private: 85b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Element* top() { return top_; } 86b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org void set_top(Element* value) { top_ = value; } 87b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Element* top_; 88b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org bool* ok_; 89b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org}; 90b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 91b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 92400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.orgRegExpBuilder::RegExpBuilder(Zone* zone) 93400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org : zone_(zone), 94c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org pending_empty_(false), 95c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org characters_(NULL), 96c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org terms_(), 97c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org alternatives_() 98a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifdef DEBUG 99c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org , last_added_(ADD_NONE) 100a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif 101a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org {} 102a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 103a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 104a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushCharacters() { 105a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org pending_empty_ = false; 106a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (characters_ != NULL) { 107c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector()); 108a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org characters_ = NULL; 1097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org text_.Add(atom, zone()); 110a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_ATOM); 111a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 112a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 113a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 114a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 115a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushText() { 116a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushCharacters(); 117a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int num_text = text_.length(); 118a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (num_text == 0) { 119a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 120a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (num_text == 1) { 1217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org terms_.Add(text_.last(), zone()); 122a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 1237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org RegExpText* text = new(zone()) RegExpText(zone()); 124a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org for (int i = 0; i < num_text; i++) 1257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org text_.Get(i)->AppendToText(text, zone()); 1267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org terms_.Add(text, zone()); 127a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 128a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org text_.Clear(); 129a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 130a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 131a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 132a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddCharacter(uc16 c) { 133a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org pending_empty_ = false; 134a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (characters_ == NULL) { 1357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org characters_ = new(zone()) ZoneList<uc16>(4, zone()); 136a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 1377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org characters_->Add(c, zone()); 138a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_CHAR); 139a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 140a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 141a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 142a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddEmpty() { 143a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org pending_empty_ = true; 144a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 145a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 146a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 147a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddAtom(RegExpTree* term) { 148a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (term->IsEmpty()) { 149a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org AddEmpty(); 150a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 151a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 152a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (term->IsTextElement()) { 153a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushCharacters(); 1547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org text_.Add(term, zone()); 155a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 156a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushText(); 1577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org terms_.Add(term, zone()); 158a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 159a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_ATOM); 160a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 161a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 162a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 163a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddAssertion(RegExpTree* assert) { 164a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushText(); 1657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org terms_.Add(assert, zone()); 166a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_ASSERT); 167a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 168a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 169a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 170a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::NewAlternative() { 171a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushTerms(); 172a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 173a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 174a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 175a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushTerms() { 176a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushText(); 177a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int num_terms = terms_.length(); 178a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpTree* alternative; 179a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (num_terms == 0) { 180a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org alternative = RegExpEmpty::GetInstance(); 181a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (num_terms == 1) { 182a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org alternative = terms_.last(); 183a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 1847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org alternative = new(zone()) RegExpAlternative(terms_.GetList(zone())); 185a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 1867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org alternatives_.Add(alternative, zone()); 187a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org terms_.Clear(); 188a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_NONE); 189a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 190a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 191a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 192a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpBuilder::ToRegExp() { 193a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushTerms(); 194a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int num_alternatives = alternatives_.length(); 195a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (num_alternatives == 0) { 196a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return RegExpEmpty::GetInstance(); 197a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 198a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (num_alternatives == 1) { 199a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return alternatives_.last(); 200a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 2017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org return new(zone()) RegExpDisjunction(alternatives_.GetList(zone())); 202a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 203a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 204a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 205dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgvoid RegExpBuilder::AddQuantifierToAtom( 206dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org int min, int max, RegExpQuantifier::QuantifierType quantifier_type) { 207a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (pending_empty_) { 208a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org pending_empty_ = false; 209a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 210a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 211a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpTree* atom; 212a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (characters_ != NULL) { 213a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(last_added_ == ADD_CHAR); 214a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Last atom was character. 215a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Vector<const uc16> char_vector = characters_->ToConstVector(); 216a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int num_chars = char_vector.length(); 217a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (num_chars > 1) { 218a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1); 2197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org text_.Add(new(zone()) RegExpAtom(prefix), zone()); 220a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org char_vector = char_vector.SubVector(num_chars - 1, num_chars); 221a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 222a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org characters_ = NULL; 223c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org atom = new(zone()) RegExpAtom(char_vector); 224a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushText(); 225a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (text_.length() > 0) { 226a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(last_added_ == ADD_ATOM); 227a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org atom = text_.RemoveLast(); 228a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FlushText(); 229a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (terms_.length() > 0) { 230a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(last_added_ == ADD_ATOM); 231a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org atom = terms_.RemoveLast(); 23237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (atom->max_match() == 0) { 23337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Guaranteed to only match an empty string. 234a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_TERM); 235a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (min == 0) { 236a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 237a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 2387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org terms_.Add(atom, zone()); 239a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 240a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 241a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 242a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Only call immediately after adding an atom or character! 243a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org UNREACHABLE(); 244a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 245a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 246dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org terms_.Add( 247dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); 248a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org LAST(ADD_TERM); 249a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 250a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 251a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 2529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgHandle<String> Parser::LookupSymbol(int symbol_id) { 253fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // Length of symbol cache is the number of identified symbols. 254fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // If we are larger than that, or negative, it's not a cached symbol. 255fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // This might also happen if there is no preparser symbol data, even 256fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // if there is some preparser data. 257fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (static_cast<unsigned>(symbol_id) 258fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org >= static_cast<unsigned>(symbol_cache_.length())) { 2599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (scanner().is_literal_ascii()) { 2604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return isolate()->factory()->InternalizeOneByteString( 26159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Vector<const uint8_t>::cast(scanner().literal_ascii_string())); 2629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } else { 2634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return isolate()->factory()->InternalizeTwoByteString( 264154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org scanner().literal_utf16_string()); 2659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 266fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org } 2679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return LookupCachedSymbol(symbol_id); 268fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org} 269fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org 270fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org 2719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgHandle<String> Parser::LookupCachedSymbol(int symbol_id) { 272fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // Make sure the cache is large enough to hold the symbol identifier. 273fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (symbol_cache_.length() <= symbol_id) { 274fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // Increase length to index + 1. 275fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org symbol_cache_.AddBlock(Handle<String>::null(), 2767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org symbol_id + 1 - symbol_cache_.length(), zone()); 277fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org } 278fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org Handle<String> result = symbol_cache_.at(symbol_id); 279fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (result.is_null()) { 2809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (scanner().is_literal_ascii()) { 2814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org result = isolate()->factory()->InternalizeOneByteString( 28259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Vector<const uint8_t>::cast(scanner().literal_ascii_string())); 2839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } else { 2844a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org result = isolate()->factory()->InternalizeTwoByteString( 285154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org scanner().literal_utf16_string()); 2869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 287fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org symbol_cache_.at(symbol_id) = result; 2885b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org return result; 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2907979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org isolate()->counters()->total_preparse_symbols_skipped()->Increment(); 291fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org return result; 292fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org} 29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 295d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgFunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { 296d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // The current pre-data entry must be a FunctionEntry with the given 297d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // start position. 2985b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org if ((function_index_ + FunctionEntry::kSize <= store_.length()) 2995b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org && (static_cast<int>(store_[function_index_]) == start)) { 3005b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org int index = function_index_; 3015b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org function_index_ += FunctionEntry::kSize; 302d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org return FunctionEntry(store_.SubVector(index, 303d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org index + FunctionEntry::kSize)); 30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return FunctionEntry(); 30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 309d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.comint ScriptDataImpl::GetSymbolIdentifier() { 310d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com return ReadNumber(&symbol_data_); 3115b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org} 3125b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 3135b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 3145b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.orgbool ScriptDataImpl::SanityCheck() { 3155b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org // Check that the header data is valid and doesn't specify 3165b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org // point to positions outside the store. 317beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (store_.length() < PreparseDataConstants::kHeaderSize) return false; 318beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (magic() != PreparseDataConstants::kMagicNumber) return false; 319beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (version() != PreparseDataConstants::kCurrentVersion) return false; 3205b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org if (has_error()) { 3215b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org // Extra sane sanity check for error message encoding. 322beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (store_.length() <= PreparseDataConstants::kHeaderSize 323beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org + PreparseDataConstants::kMessageTextPos) { 324beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org return false; 325beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org } 326beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (Read(PreparseDataConstants::kMessageStartPos) > 327beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org Read(PreparseDataConstants::kMessageEndPos)) { 328beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org return false; 329beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org } 330beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos); 331beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org int pos = PreparseDataConstants::kMessageTextPos; 3325b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org for (unsigned int i = 0; i <= arg_count; i++) { 333beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) { 334beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org return false; 335beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org } 3365b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org int length = static_cast<int>(Read(pos)); 3375b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org if (length < 0) return false; 3385b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org pos += 1 + length; 3395b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org } 340beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (store_.length() < PreparseDataConstants::kHeaderSize + pos) { 341beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org return false; 342beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org } 3435b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org return true; 3445b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org } 3455b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org // Check that the space allocated for function entries is sane. 3465b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org int functions_size = 347beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]); 3485b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org if (functions_size < 0) return false; 3495b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org if (functions_size % FunctionEntry::kSize != 0) return false; 3505b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org // Check that the count of symbols is non-negative. 3515b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org int symbol_count = 352beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org static_cast<int>(store_[PreparseDataConstants::kSymbolCountOffset]); 3535b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org if (symbol_count < 0) return false; 354d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Check that the total size has room for header and function entries. 3555b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org int minimum_size = 356beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org PreparseDataConstants::kHeaderSize + functions_size; 3575b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org if (store_.length() < minimum_size) return false; 35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 35943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 36043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3622ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 36365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgconst char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { 36443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int length = start[0]; 36543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen char* result = NewArray<char>(length + 1); 36665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org for (int i = 0; i < length; i++) { 36743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result[i] = start[i + 1]; 36865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 36943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result[length] = '\0'; 37043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (chars != NULL) *chars = length; 37143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 37243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 37343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 374e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 37543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenScanner::Location ScriptDataImpl::MessageLocation() { 376beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org int beg_pos = Read(PreparseDataConstants::kMessageStartPos); 377beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org int end_pos = Read(PreparseDataConstants::kMessageEndPos); 37843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return Scanner::Location(beg_pos, end_pos); 37943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 38043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst char* ScriptDataImpl::BuildMessage() { 383beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos); 38465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org return ReadString(start, NULL); 38543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 38643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenVector<const char*> ScriptDataImpl::BuildArgs() { 389beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org int arg_count = Read(PreparseDataConstants::kMessageArgCountPos); 39043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char** array = NewArray<const char*>(arg_count); 391d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Position after text found by skipping past length field and 392d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // length field content words. 393beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org int pos = PreparseDataConstants::kMessageTextPos + 1 394beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org + Read(PreparseDataConstants::kMessageTextPos); 39543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < arg_count; i++) { 39643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int count = 0; 39765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org array[i] = ReadString(ReadAddress(pos), &count); 39843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen pos += count + 1; 39943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 40043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return Vector<const char*>(array, arg_count); 40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 40243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 40343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 40443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenunsigned ScriptDataImpl::Read(int position) { 405beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org return store_[PreparseDataConstants::kHeaderSize + position]; 40643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 40743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 40943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenunsigned* ScriptDataImpl::ReadAddress(int position) { 410beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org return &store_[PreparseDataConstants::kHeaderSize + position]; 41143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 41243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 41343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 414dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgScope* Parser::NewScope(Scope* parent, ScopeType scope_type) { 415dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Scope* result = new(zone()) Scope(parent, scope_type, zone()); 416394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com result->Initialize(); 41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 41943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 42143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 42243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Target is a support class to facilitate manipulation of the 42343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Parser's target_stack_ (the stack of potential 'break' and 42443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 'continue' statement targets). Upon construction, a new target is 42543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// added; it is removed upon destruction. 42643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 42743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Target BASE_EMBEDDED { 42843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 429e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target(Target** variable, AstNode* node) 430e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org : variable_(variable), node_(node), previous_(*variable) { 431e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org *variable = this; 43243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ~Target() { 435e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org *variable_ = previous_; 43643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 43743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 438b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Target* previous() { return previous_; } 4390b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org AstNode* node() { return node_; } 440b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 44143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 442e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target** variable_; 4430b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org AstNode* node_; 444b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Target* previous_; 44543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 44643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 44743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 44843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass TargetScope BASE_EMBEDDED { 44943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 450e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org explicit TargetScope(Target** variable) 451e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org : variable_(variable), previous_(*variable) { 452e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org *variable = NULL; 45343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 45443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ~TargetScope() { 456e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org *variable_ = previous_; 45743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 460e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target** variable_; 461b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Target* previous_; 46243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 46343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 46443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 46543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 466c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org// FunctionState and BlockState together implement the parser's scope stack. 467c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org// The parser's current scope is in top_scope_. The BlockState and 468c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org// FunctionState constructors push on the scope stack and the destructors 469c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org// pop. They are also used to hold the parser's per-function and per-block 470c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org// state. 471394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 472c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgclass Parser::BlockState BASE_EMBEDDED { 473394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com public: 474c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org BlockState(Parser* parser, Scope* scope) 475394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com : parser_(parser), 476c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org outer_scope_(parser->top_scope_) { 477394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com parser->top_scope_ = scope; 478394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 479394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 480c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ~BlockState() { parser_->top_scope_ = outer_scope_; } 481394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 482394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com private: 483394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Parser* parser_; 484c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Scope* outer_scope_; 485394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}; 486394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 488c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgParser::FunctionState::FunctionState(Parser* parser, 489c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Scope* scope, 490c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Isolate* isolate) 491c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), 49204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org next_handler_index_(0), 493c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org expected_property_count_(0), 494e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org generator_object_variable_(NULL), 495c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org parser_(parser), 496c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org outer_function_state_(parser->current_function_state_), 497c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org outer_scope_(parser->top_scope_), 498b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org saved_ast_node_id_(isolate->ast_node_id()), 4995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org factory_(isolate, parser->zone()) { 500ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org parser->top_scope_ = scope; 501c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org parser->current_function_state_ = this; 502471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt()); 503ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 504ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 505ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 506c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgParser::FunctionState::~FunctionState() { 507c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org parser_->top_scope_ = outer_scope_; 508c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org parser_->current_function_state_ = outer_function_state_; 50956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org if (outer_function_state_ != NULL) { 51056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org parser_->isolate()->set_ast_node_id(saved_ast_node_id_); 51156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org } 512ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 513ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 514ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 51543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 51643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The CHECK_OK macro is a convenient macro to enforce error 51743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// handling for functions that may fail (by returning !*ok). 51843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 51943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// CAUTION: This macro appends extra statements after a call, 52043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// thus it must never be used where only a single statement 52143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// is correct (e.g. an if statement branch w/o braces)! 52243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 52343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define CHECK_OK ok); \ 52443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!*ok) return NULL; \ 52543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ((void)0 52643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DUMMY ) // to make indentation work 52743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DUMMY 52843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 529a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#define CHECK_FAILED /**/); \ 530a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (failed_) return NULL; \ 531a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ((void)0 532a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#define DUMMY ) // to make indentation work 533a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#undef DUMMY 53443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 53543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 53643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of Parser 53743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 538e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgParser::Parser(CompilationInfo* info) 539a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()), 540a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org isolate_(info->isolate()), 541e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org symbol_cache_(0, info->zone()), 5425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org script_(info->script()), 543a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org scanner_(isolate_->unicode_cache()), 5441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org reusable_preparser_(NULL), 54543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen top_scope_(NULL), 5461e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org original_scope_(NULL), 547c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org current_function_state_(NULL), 54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen target_stack_(NULL), 549e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org extension_(info->extension()), 550e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org pre_parse_data_(NULL), 551a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org fni_(NULL), 552400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org parenthesized_function_(false), 5535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org zone_(info->zone()), 5545a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org info_(info) { 5555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(!script_.is_null()); 55656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org isolate_->set_ast_node_id(0); 557e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); 558e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_modules(!info->is_native() && FLAG_harmony_modules); 559e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); 560e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_lazy(false); // Must be explicitly enabled. 561e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_generators(FLAG_harmony_generators); 5621fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org set_allow_for_of(FLAG_harmony_iteration); 563ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); 56443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 56543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 56643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgFunctionLiteral* Parser::ParseProgram() { 5684000f228dd279f96628ed845f1e81d01ba7e14d8jkummerow@chromium.org // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, 5694000f228dd279f96628ed845f1e81d01ba7e14d8jkummerow@chromium.org // see comment for HistogramTimerScope class. 5704000f228dd279f96628ed845f1e81d01ba7e14d8jkummerow@chromium.org HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); 57127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Handle<String> source(String::cast(script_->source())); 5727979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org isolate()->counters()->total_parse_size()->Increment(source->length()); 573dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org ElapsedTimer timer; 574dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (FLAG_trace_parse) { 575dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org timer.Start(); 576dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } 5777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); 57843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 57943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize parser state. 580ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org source->TryFlatten(); 581304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FunctionLiteral* result; 5825f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org if (source->IsExternalTwoByteString()) { 5835f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Notice that the stream is destroyed at the end of the branch block. 5845f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // The last line of the blocks can't be moved outside, even though they're 5855f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // identical calls. 586154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ExternalTwoByteStringUtf16CharacterStream stream( 5875f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 5889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org scanner_.Initialize(&stream); 5891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org result = DoParseProgram(info(), source); 5905f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else { 591154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org GenericStringUtf16CharacterStream stream(source, 0, source->length()); 5929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org scanner_.Initialize(&stream); 5931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org result = DoParseProgram(info(), source); 5945f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 595304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 596304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (FLAG_trace_parse && result != NULL) { 597dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org double ms = timer.Elapsed().InMillisecondsF(); 598304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (info()->is_eval()) { 599304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF("[parsing eval"); 600304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } else if (info()->script()->name()->IsString()) { 601304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org String* name = String::cast(info()->script()->name()); 602304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org SmartArrayPointer<char> name_chars = name->ToCString(); 603304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF("[parsing script: %s", *name_chars); 604304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } else { 605304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF("[parsing script"); 606304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 607304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF(" - took %0.3f ms]\n", ms); 608304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 609304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org return result; 6105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 6115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 6125f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 61327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgFunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, 6141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> source) { 615394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(top_scope_ == NULL); 61643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(target_stack_ == NULL); 617e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); 61843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<String> no_name = isolate()->factory()->empty_string(); 62043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 62143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FunctionLiteral* result = NULL; 62227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 62327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org info->SetGlobalScope(scope); 624355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org if (!info->context().is_null()) { 625355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); 626355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org } 6271e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org original_scope_ = scope; 6282c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (info->is_eval()) { 6292c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { 6302c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org scope = NewScope(scope, EVAL_SCOPE); 6312c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } 632355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org } else if (info->is_global()) { 633355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org scope = NewScope(scope, GLOBAL_SCOPE); 63427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } 635394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->set_start_position(0); 636394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->set_end_position(source->length()); 637355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 638cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org // Compute the parsing mode. 639e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; 640e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (allow_natives_syntax() || 641e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org extension_ != NULL || 642e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org scope->is_eval_scope()) { 643cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org mode = PARSE_EAGERLY; 644cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org } 645cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org ParsingModeScope parsing_mode(this, mode); 646cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org 647f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Enters 'scope'. 648e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FunctionState function_state(this, scope, isolate()); 649f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 6501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org top_scope_->SetLanguageMode(info->language_mode()); 6517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 65243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool ok = true; 653a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int beg_pos = scanner().location().beg_pos; 65433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); 6551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (ok && !top_scope_->is_classic_mode()) { 656a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org CheckOctalLiteral(beg_pos, scanner().location().end_pos, &ok); 6570ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 6581805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 6591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (ok && is_extended_mode()) { 6602c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org CheckConflictingVarDeclarations(top_scope_, &ok); 6611805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 6621805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 6639faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { 6649faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (body->length() != 1 || 6659faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org !body->at(0)->IsExpressionStatement() || 6669faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org !body->at(0)->AsExpressionStatement()-> 6679faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org expression()->IsFunctionLiteral()) { 668f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ReportMessage("single_function_literal", Vector<const char*>::empty()); 6699faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org ok = false; 6709faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 6719faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 6729faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org 67343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (ok) { 674b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewFunctionLiteral( 675911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org no_name, 676911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org top_scope_, 677fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org body, 678c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org function_state.materialized_literal_count(), 679c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org function_state.expected_property_count(), 68004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org function_state.handler_count(), 681911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 0, 68256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org FunctionLiteral::kNoDuplicateParameters, 6837c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org FunctionLiteral::ANONYMOUS_EXPRESSION, 684471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FunctionLiteral::kGlobalOrEval, 685f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org FunctionLiteral::kNotParenthesized, 686a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org FunctionLiteral::kNotGenerator, 687a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org 0); 688b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result->set_ast_properties(factory()->visitor()->ast_properties()); 6892c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org result->set_dont_optimize_reason( 6902c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org factory()->visitor()->dont_optimize_reason()); 691a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org } else if (stack_overflow()) { 692ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()->StackOverflow(); 69343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 69443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 69643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure the target stack is empty. 69743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(target_stack_ == NULL); 69843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 69943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 70043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 70143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 702f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 7035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgFunctionLiteral* Parser::ParseLazy() { 704dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); 705f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org Handle<String> source(String::cast(script_->source())); 7067979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org isolate()->counters()->total_parse_size()->Increment(source->length()); 707dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org ElapsedTimer timer; 708dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (FLAG_trace_parse) { 709dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org timer.Start(); 710dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } 7115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared_info = info()->shared_info(); 712304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 7135f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Initialize parser state. 7145f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org source->TryFlatten(); 715304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FunctionLiteral* result; 7165f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org if (source->IsExternalTwoByteString()) { 717154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ExternalTwoByteStringUtf16CharacterStream stream( 7185f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Handle<ExternalTwoByteString>::cast(source), 7194d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org shared_info->start_position(), 7204d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org shared_info->end_position()); 7211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org result = ParseLazy(&stream); 7225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else { 723154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org GenericStringUtf16CharacterStream stream(source, 724154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org shared_info->start_position(), 725154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org shared_info->end_position()); 7261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org result = ParseLazy(&stream); 7275f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 728304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 729304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (FLAG_trace_parse && result != NULL) { 730dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org double ms = timer.Elapsed().InMillisecondsF(); 731de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); 732304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF("[parsing function: %s - took %0.3f ms]\n", *name_chars, ms); 733304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 734304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org return result; 7355f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 7365f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 7375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 7381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgFunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { 7395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared_info = info()->shared_info(); 7409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org scanner_.Initialize(source); 741394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(top_scope_ == NULL); 7425f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org ASSERT(target_stack_ == NULL); 7435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 7444d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org Handle<String> name(String::cast(shared_info->name())); 7457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); 74665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->PushEnclosingName(name); 74765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 748471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 74943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 75043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Place holder for the result. 75143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FunctionLiteral* result = NULL; 75243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 75343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen { 75443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse the function literal. 755394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 7565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org info()->SetGlobalScope(scope); 7575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (!info()->closure().is_null()) { 7585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, 7597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org zone()); 7604d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } 7611e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org original_scope_ = scope; 762e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FunctionState function_state(this, scope, isolate()); 7635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); 7641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(scope->language_mode() != EXTENDED_MODE || 7655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org info()->is_extended_mode()); 7665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(info()->language_mode() == shared_info->language_mode()); 7671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org scope->SetLanguageMode(shared_info->language_mode()); 768dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org FunctionLiteral::FunctionType function_type = shared_info->is_expression() 7697c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org ? (shared_info->is_anonymous() 7707c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org ? FunctionLiteral::ANONYMOUS_EXPRESSION 7717c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org : FunctionLiteral::NAMED_EXPRESSION) 7727c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org : FunctionLiteral::DECLARATION; 77343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool ok = true; 77483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org result = ParseFunctionLiteral(name, 7757c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org false, // Strict mode name already checked. 776f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org shared_info->is_generator(), 7777c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org RelocInfo::kNoPosition, 778dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org function_type, 7797c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org &ok); 78043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure the results agree. 78143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(ok == (result != NULL)); 78243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 78343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 78443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure the target stack is empty. 78543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(target_stack_ == NULL); 78643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 78743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (result == NULL) { 788a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org if (stack_overflow()) isolate()->StackOverflow(); 789a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 7904d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org Handle<String> inferred_name(shared_info->inferred_name()); 791a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org result->set_inferred_name(inferred_name); 79243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 79343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 79443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 79543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 796f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 797bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.orgHandle<String> Parser::GetSymbol() { 798d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com int symbol_id = -1; 799e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (pre_parse_data() != NULL) { 800e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org symbol_id = pre_parse_data()->GetSymbolIdentifier(); 8015b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org } 8029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return LookupSymbol(symbol_id); 8035b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org} 8045b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 8055b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 806dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgvoid Parser::ReportMessage(const char* message, Vector<const char*> args) { 8075f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Scanner::Location source_location = scanner().location(); 808dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org ReportMessageAt(source_location, message, args); 809fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org} 810fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org 811fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org 812dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgvoid Parser::ReportMessage(const char* message, Vector<Handle<String> > args) { 813bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Scanner::Location source_location = scanner().location(); 814dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org ReportMessageAt(source_location, message, args); 815bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com} 816bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 817bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 818fa943b736b1d996084393011529d568165bb5d83lrn@chromium.orgvoid Parser::ReportMessageAt(Scanner::Location source_location, 819dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org const char* message, 820fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org Vector<const char*> args) { 82143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen MessageLocation location(script_, 822c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org source_location.beg_pos, 823c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org source_location.end_pos); 824ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Factory* factory = isolate()->factory(); 825ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<FixedArray> elements = factory->NewFixedArray(args.length()); 82643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < args.length(); i++) { 827ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); 8288f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org elements->set(i, *arg_string); 82943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 830ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<JSArray> array = factory->NewJSArrayWithElements(elements); 831dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<Object> result = factory->NewSyntaxError(message, array); 832ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()->Throw(*result, &location); 83343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 83443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 83543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 836c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid Parser::ReportMessageAt(Scanner::Location source_location, 837dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org const char* message, 838c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Vector<Handle<String> > args) { 839c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org MessageLocation location(script_, 840c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org source_location.beg_pos, 841c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org source_location.end_pos); 842ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Factory* factory = isolate()->factory(); 843ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<FixedArray> elements = factory->NewFixedArray(args.length()); 844c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0; i < args.length(); i++) { 8458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org elements->set(i, *args[i]); 846c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 847ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<JSArray> array = factory->NewJSArrayWithElements(elements); 848dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<Object> result = factory->NewSyntaxError(message, array); 849ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()->Throw(*result, &location); 850c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 851c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 852c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 853fa943b736b1d996084393011529d568165bb5d83lrn@chromium.orgvoid* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 85443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int end_token, 8552c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org bool is_eval, 85633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org bool is_global, 85743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* ok) { 85843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // SourceElements :: 859f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // (ModuleElement)* <end_token> 86043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 86143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Allocate a target stack to use for this set of source 86243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // elements. This way, all scripts and functions get their own 86343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // target stack thus avoiding illegal breaks and continues across 86443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // functions. 865e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org TargetScope scope(&this->target_stack_); 86643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 86743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(processor != NULL); 8680a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org bool directive_prologue = true; // Parsing directive prologue. 8690a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 87043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != end_token) { 8710a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (directive_prologue && peek() != Token::STRING) { 8720a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; 8730a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 8740a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 8750a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Scanner::Location token_loc = scanner().peek_location(); 87633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Statement* stat; 87733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (is_global && !is_eval) { 87833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org stat = ParseModuleElement(NULL, CHECK_OK); 87933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } else { 88033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org stat = ParseBlockElement(NULL, CHECK_OK); 88133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 8820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (stat == NULL || stat->IsEmpty()) { 8830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; // End of directive prologue. 8840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org continue; 8850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 8860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 8870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (directive_prologue) { 8880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // A shot at a directive. 889f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ExpressionStatement* e_stat; 890f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Literal* literal; 8910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Still processing directive prologue? 8920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if ((e_stat = stat->AsExpressionStatement()) != NULL && 8930a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org (literal = e_stat->expression()->AsLiteral()) != NULL && 8941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org literal->value()->IsString()) { 8951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> directive = Handle<String>::cast(literal->value()); 8960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 8970a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Check "use strict" directive (ES5 14.1). 8981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (top_scope_->is_classic_mode() && 8994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org directive->Equals(isolate()->heap()->use_strict_string()) && 9000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org token_loc.end_pos - token_loc.beg_pos == 9014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->heap()->use_strict_string()->length() + 2) { 9022c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // TODO(mstarzinger): Global strict eval calls, need their own scope 9032c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // as specified in ES5 10.4.2(3). The correct fix would be to always 9042c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // add this scope in DoParseProgram(), but that requires adaptations 9052c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // all over the code base, so we go with a quick-fix for now. 906cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org // In the same manner, we have to patch the parsing mode. 9072c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (is_eval && !top_scope_->is_eval_scope()) { 9082c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org ASSERT(top_scope_->is_global_scope()); 9092c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Scope* scope = NewScope(top_scope_, EVAL_SCOPE); 9102c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org scope->set_start_position(top_scope_->start_position()); 9112c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org scope->set_end_position(top_scope_->end_position()); 9122c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org top_scope_ = scope; 913cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org mode_ = PARSE_EAGERLY; 9142c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } 9151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // TODO(ES6): Fix entering extended mode, once it is specified. 916e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org top_scope_->SetLanguageMode(allow_harmony_scoping() 9171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ? EXTENDED_MODE : STRICT_MODE); 9180a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // "use strict" is the only directive for now. 9190a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; 9200a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 9210a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 9220a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // End of the directive prologue. 9230a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; 9240a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 9250a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 9260a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 9277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org processor->Add(stat, zone()); 92843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 929911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 93043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; 93143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 93243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 93343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 934f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgStatement* Parser::ParseModuleElement(ZoneStringList* labels, 935f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org bool* ok) { 936f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // (Ecma 262 5th Edition, clause 14): 937f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // SourceElement: 938f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Statement 939f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // FunctionDeclaration 940f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // 941f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // In harmony mode we allow additionally the following productions 942f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModuleElement: 943f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // LetDeclaration 944f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ConstDeclaration 945f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModuleDeclaration 946f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ImportDeclaration 947f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ExportDeclaration 948f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // GeneratorDeclaration 949f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 950f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org switch (peek()) { 951f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::FUNCTION: 952812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseFunctionDeclaration(NULL, ok); 953f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::LET: 954f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::CONST: 955812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseVariableStatement(kModuleElement, NULL, ok); 956f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::IMPORT: 957f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseImportDeclaration(ok); 958f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::EXPORT: 959f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseExportDeclaration(ok); 960a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org default: { 961a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org Statement* stmt = ParseStatement(labels, CHECK_OK); 962a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org // Handle 'module' as a context-sensitive keyword. 963a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org if (FLAG_harmony_modules && 964a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org peek() == Token::IDENTIFIER && 965a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org !scanner().HasAnyLineTerminatorBeforeNext() && 966a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org stmt != NULL) { 967a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org ExpressionStatement* estmt = stmt->AsExpressionStatement(); 968a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org if (estmt != NULL && 969a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org estmt->expression()->AsVariableProxy() != NULL && 970a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org estmt->expression()->AsVariableProxy()->name()->Equals( 9714a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->heap()->module_string()) && 972a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org !scanner().literal_contains_escapes()) { 973812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseModuleDeclaration(NULL, ok); 974a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 975a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 976a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org return stmt; 977a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 978f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 979f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 980f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 981f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 98281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.orgStatement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { 983f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModuleDeclaration: 984f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // 'module' Identifier Module 985f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 986a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 987f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Handle<String> name = ParseIdentifier(CHECK_OK); 988bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 989bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 990bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 991bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Module %s...\n", name->ToAsciiArray()); 992bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 993bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 994812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* module = ParseModule(CHECK_OK); 9958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); 996812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 997a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewModuleDeclaration(proxy, module, top_scope_, pos); 998812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 999812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1000bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1001bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 1002bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Module %s.\n", name->ToAsciiArray()); 1003bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1004bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 1005bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("module %s : ", name->ToAsciiArray()); 1006bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com module->interface()->Print(); 1007bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1008bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1009bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 10107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (names) names->Add(name, zone()); 101181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org if (module->body() == NULL) 1012a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewEmptyStatement(pos); 101381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org else 1014a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewModuleStatement(proxy, module->body(), pos); 1015f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1016f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1017f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1018f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModule(bool* ok) { 1019f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Module: 1020f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // '{' ModuleElement '}' 1021812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // '=' ModulePath ';' 1022812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'at' String ';' 1023f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1024f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org switch (peek()) { 1025f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::LBRACE: 1026f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseModuleLiteral(ok); 1027f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1028812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::ASSIGN: { 1029f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::ASSIGN, CHECK_OK); 1030812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* result = ParseModulePath(CHECK_OK); 1031812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1032812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return result; 1033812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1034f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1035812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org default: { 10361fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ExpectContextualKeyword(CStrVector("at"), CHECK_OK); 1037812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* result = ParseModuleUrl(CHECK_OK); 1038812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1039812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return result; 1040812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1041f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1042f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1043f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1044f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1045f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleLiteral(bool* ok) { 1046f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Module: 1047f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // '{' ModuleElement '}' 1048f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1049a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 1050f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Construct block expecting 16 statements. 1051a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); 1052bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1053bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) PrintF("# Literal "); 1054bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1055f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Scope* scope = NewScope(top_scope_, MODULE_SCOPE); 1056f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1057f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::LBRACE, CHECK_OK); 1058f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org scope->set_start_position(scanner().location().beg_pos); 1059f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org scope->SetLanguageMode(EXTENDED_MODE); 1060f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1061f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org { 1062f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org BlockState block_state(this, scope); 10637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector collector(zone()); 1064f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Target target(&this->target_stack_, &collector); 1065f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Target target_body(&this->target_stack_, body); 1066f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1067f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org while (peek() != Token::RBRACE) { 1068f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Statement* stat = ParseModuleElement(NULL, CHECK_OK); 1069f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (stat && !stat->IsEmpty()) { 1070400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body->AddStatement(stat, zone()); 1071f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1072f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1073f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1074f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1075f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::RBRACE, CHECK_OK); 1076f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org scope->set_end_position(scanner().location().end_pos); 1077ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com body->set_scope(scope); 1078bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 107981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // Check that all exports are bound. 1080ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Interface* interface = scope->interface(); 108181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org for (Interface::Iterator it = interface->iterator(); 108281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org !it.done(); it.Advance()) { 108381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org if (scope->LocalLookup(it.name()) == NULL) { 108481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org Handle<String> name(it.name()); 108581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org ReportMessage("module_export_undefined", 108681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org Vector<Handle<String> >(&name, 1)); 108781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org *ok = false; 108881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org return NULL; 108981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org } 109081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org } 109181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org 1092ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com interface->MakeModule(ok); 109381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org ASSERT(*ok); 1094ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com interface->Freeze(ok); 109581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org ASSERT(*ok); 1096a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewModuleLiteral(body, interface, pos); 1097f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1098f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1099f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1100f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModulePath(bool* ok) { 1101f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModulePath: 1102f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Identifier 1103f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModulePath '.' Identifier 1104f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1105a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 1106f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Module* result = ParseModuleVariable(CHECK_OK); 1107f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org while (Check(Token::PERIOD)) { 1108f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Handle<String> name = ParseIdentifierName(CHECK_OK); 1109bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1110bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 1111bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Path .%s ", name->ToAsciiArray()); 1112bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1113a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Module* member = factory()->NewModulePath(result, name, pos); 11147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org result->interface()->Add(name, member->interface(), zone(), ok); 1115bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (!*ok) { 1116bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1117bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 1118bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); 1119bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("result: "); 1120bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com result->interface()->Print(); 1121bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("member: "); 1122bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com member->interface()->Print(); 1123bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1124bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1125bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); 1126bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com return NULL; 1127bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1128bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com result = member; 1129f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1130f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1131f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return result; 1132f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1133f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1134f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1135f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleVariable(bool* ok) { 1136f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModulePath: 1137f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Identifier 1138f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1139a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 1140f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Handle<String> name = ParseIdentifier(CHECK_OK); 1141bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1142bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 1143bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Module variable %s ", name->ToAsciiArray()); 1144bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1145f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org VariableProxy* proxy = top_scope_->NewUnresolved( 114628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org factory(), name, Interface::NewModule(zone()), 114728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org scanner().location().beg_pos); 1148bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1149a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewModuleVariable(proxy, pos); 1150f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1151f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1152f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1153f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleUrl(bool* ok) { 1154f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Module: 1155812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // String 1156f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1157a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 1158f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::STRING, CHECK_OK); 1159bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org Handle<String> symbol = GetSymbol(); 1160f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1161bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // TODO(ES6): Request JS resource from environment... 1162bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1163bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1164bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) PrintF("# Url "); 1165bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1166ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 11678e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Create an empty literal as long as the feature isn't finished. 11688e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org USE(symbol); 11698e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Scope* scope = NewScope(top_scope_, MODULE_SCOPE); 1170a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 11718e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org body->set_scope(scope); 11728e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Interface* interface = scope->interface(); 1173a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Module* result = factory()->NewModuleLiteral(body, interface, pos); 1174ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com interface->Freeze(ok); 117581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org ASSERT(*ok); 117681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org interface->Unify(scope->interface(), zone(), ok); 117781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org ASSERT(*ok); 1178ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com return result; 1179f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1180f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1181f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1182812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgModule* Parser::ParseModuleSpecifier(bool* ok) { 1183812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ModuleSpecifier: 1184812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // String 1185812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ModulePath 1186812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1187812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org if (peek() == Token::STRING) { 1188812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseModuleUrl(ok); 1189812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } else { 1190812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseModulePath(ok); 1191812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1192812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 1193812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1194812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1195f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgBlock* Parser::ParseImportDeclaration(bool* ok) { 1196812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ImportDeclaration: 1197812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' 1198812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 1199812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // TODO(ES6): implement destructuring ImportSpecifiers 1200812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1201a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 1202812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Expect(Token::IMPORT, CHECK_OK); 12037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneStringList names(1, zone()); 1204812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1205812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Handle<String> name = ParseIdentifierName(CHECK_OK); 12067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1207812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org while (peek() == Token::COMMA) { 1208812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Consume(Token::COMMA); 1209812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org name = ParseIdentifierName(CHECK_OK); 12107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1211812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1212812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 12131fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ExpectContextualKeyword(CStrVector("from"), CHECK_OK); 1214812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* module = ParseModuleSpecifier(CHECK_OK); 1215812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1216812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1217812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Generate a separate declaration for each identifier. 1218812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // TODO(ES6): once we implement destructuring, make that one declaration. 1219a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); 1220812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org for (int i = 0; i < names.length(); ++i) { 1221bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1222bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 1223bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Import %s ", names[i]->ToAsciiArray()); 1224bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 12257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Interface* interface = Interface::NewUnknown(zone()); 12267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org module->interface()->Add(names[i], interface, zone(), ok); 1227bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (!*ok) { 1228bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1229bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 1230bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); 1231bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("module: "); 1232bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com module->interface()->Print(); 1233bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1234bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1235bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); 1236bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com return NULL; 1237bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1238bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com VariableProxy* proxy = NewUnresolved(names[i], LET, interface); 1239812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1240a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewImportDeclaration(proxy, module, top_scope_, pos); 1241812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 1242812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1243812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1244812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return block; 1245f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1246f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1247f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1248812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgStatement* Parser::ParseExportDeclaration(bool* ok) { 1249812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ExportDeclaration: 1250812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' Identifier (',' Identifier)* ';' 1251812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' VariableDeclaration 1252812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' FunctionDeclaration 1253f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // 'export' GeneratorDeclaration 1254812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' ModuleDeclaration 1255812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 1256812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // TODO(ES6): implement structuring ExportSpecifiers 1257812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1258812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Expect(Token::EXPORT, CHECK_OK); 1259812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1260812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Statement* result = NULL; 12617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneStringList names(1, zone()); 1262812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org switch (peek()) { 1263812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::IDENTIFIER: { 1264a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 1265812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Handle<String> name = ParseIdentifier(CHECK_OK); 1266812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Handle 'module' as a context-sensitive keyword. 126759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { 12687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1269812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org while (peek() == Token::COMMA) { 1270812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Consume(Token::COMMA); 1271812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org name = ParseIdentifier(CHECK_OK); 12727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1273812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1274812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1275a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewEmptyStatement(pos); 1276812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } else { 1277812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org result = ParseModuleDeclaration(&names, CHECK_OK); 1278812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1279812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 1280812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1281812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1282812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::FUNCTION: 1283812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org result = ParseFunctionDeclaration(&names, CHECK_OK); 1284812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 1285812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1286812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::VAR: 1287812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::LET: 1288812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::CONST: 1289812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); 1290812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 1291812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1292812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org default: 1293812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org *ok = false; 1294812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ReportUnexpectedToken(scanner().current_token()); 1295812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return NULL; 1296812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1297812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1298bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Extract declared names into export declarations and interface. 1299bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Interface* interface = top_scope_->interface(); 1300812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org for (int i = 0; i < names.length(); ++i) { 1301bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1302bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 1303bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Export %s ", names[i]->ToAsciiArray()); 1304bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 13057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Interface* inner = Interface::NewUnknown(zone()); 13067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org interface->Add(names[i], inner, zone(), CHECK_OK); 13077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (!*ok) 13087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org return NULL; 1309bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com VariableProxy* proxy = NewUnresolved(names[i], LET, inner); 1310bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com USE(proxy); 1311bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // TODO(rossberg): Rethink whether we actually need to store export 1312bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // declarations (for compilation?). 1313bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // ExportDeclaration* declaration = 1314a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org // factory()->NewExportDeclaration(proxy, top_scope_, position); 1315bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // top_scope_->AddDeclaration(declaration); 1316812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1317812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1318812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ASSERT(result != NULL); 1319812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return result; 1320f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1321f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1322f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1323f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgStatement* Parser::ParseBlockElement(ZoneStringList* labels, 1324f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org bool* ok) { 1325f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // (Ecma 262 5th Edition, clause 14): 1326f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // SourceElement: 1327f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Statement 1328f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // FunctionDeclaration 1329f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // 1330f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // In harmony mode we allow additionally the following productions 1331f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // BlockElement (aka SourceElement): 1332f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // LetDeclaration 1333f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ConstDeclaration 1334f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // GeneratorDeclaration 1335f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1336f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org switch (peek()) { 1337f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::FUNCTION: 1338812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseFunctionDeclaration(NULL, ok); 1339f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::LET: 1340f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::CONST: 1341812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseVariableStatement(kModuleElement, NULL, ok); 1342f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org default: 1343f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseStatement(labels, ok); 1344f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1345f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1346f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1347f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 134843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { 134943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Statement :: 135043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Block 135143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableStatement 135243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // EmptyStatement 135343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ExpressionStatement 135443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IfStatement 135543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IterationStatement 135643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ContinueStatement 135743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // BreakStatement 135843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ReturnStatement 135943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WithStatement 136043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LabelledStatement 136143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // SwitchStatement 136243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ThrowStatement 136343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TryStatement 136443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // DebuggerStatement 136543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 136643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note: Since labels can only be used by 'break' and 'continue' 136743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // statements, which themselves are only valid within blocks, 136843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // iterations or 'switch' statements (i.e., BreakableStatements), 136943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // labels can be simply ignored in all other cases; except for 13703291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // trivial labeled break statements 'label: break label' which is 137143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parsed into an empty statement. 137243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (peek()) { 137343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LBRACE: 137443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return ParseBlock(labels, ok); 137543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 137643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::CONST: // fall through 13771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org case Token::LET: 137843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::VAR: 1379a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseVariableStatement(kStatement, NULL, ok); 138043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 138143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SEMICOLON: 138243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 1383a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewEmptyStatement(RelocInfo::kNoPosition); 138443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 138543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::IF: 1386a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseIfStatement(labels, ok); 138743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 138843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::DO: 1389a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseDoWhileStatement(labels, ok); 139043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 139143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::WHILE: 1392a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseWhileStatement(labels, ok); 139343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 139443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::FOR: 1395a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseForStatement(labels, ok); 139643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 139743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::CONTINUE: 1398a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseContinueStatement(ok); 139943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 140043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::BREAK: 1401a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseBreakStatement(labels, ok); 140243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 140343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::RETURN: 1404a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseReturnStatement(ok); 140543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 140643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::WITH: 1407a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseWithStatement(labels, ok); 140843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 140943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SWITCH: 1410a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseSwitchStatement(labels, ok); 141143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 141243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::THROW: 1413a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseThrowStatement(ok); 141443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 141543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::TRY: { 141643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // NOTE: It is somewhat complicated to have labels on 141743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // try-statements. When breaking out of a try-finally statement, 141843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // one must take great care not to treat it as a 141943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // fall-through. It is much easier just to wrap the entire 142043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // try-statement in a statement block and put the labels there 1421a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* result = 1422a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition); 1423e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, result); 142443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TryStatement* statement = ParseTryStatement(CHECK_OK); 1425400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org if (result) result->AddStatement(statement, zone()); 142643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 142743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 142843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 14299ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org case Token::FUNCTION: { 1430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // FunctionDeclaration is only allowed in the context of SourceElements 1431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // (Ecma 262 5th Edition, clause 14): 1432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // SourceElement: 1433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Statement 1434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // FunctionDeclaration 1435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Common language extension is to allow function declaration in place 1436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of any statement. This language extension is disabled in strict mode. 1437f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // 1438f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // In Harmony mode, this case also handles the extension: 1439f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Statement: 1440f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // GeneratorDeclaration 14411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode()) { 14429ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org ReportMessageAt(scanner().peek_location(), "strict_function", 14439ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org Vector<const char*>::empty()); 14449ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org *ok = false; 14459ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org return NULL; 14469ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 1447812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseFunctionDeclaration(NULL, ok); 14489ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 144943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 145043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::DEBUGGER: 1451a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseDebuggerStatement(ok); 145243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 145343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 1454a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return ParseExpressionOrLabelledStatement(labels, ok); 145543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 145643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 145743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 145843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1459bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comVariableProxy* Parser::NewUnresolved( 1460bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Handle<String> name, VariableMode mode, Interface* interface) { 1461b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // If we are inside a function, a declaration of a var/const variable is a 1462b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // truly local variable, and the scope of the variable is always the function 1463b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // scope. 1464394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Let/const variables in harmony mode are always added to the immediately 1465394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // enclosing scope. 1466812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return DeclarationScope(mode)->NewUnresolved( 1467a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory(), name, interface, position()); 1468812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 1469812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1470812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1471812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { 1472bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com VariableProxy* proxy = declaration->proxy(); 1473bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Handle<String> name = proxy->name(); 1474812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org VariableMode mode = declaration->mode(); 1475812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Scope* declaration_scope = DeclarationScope(mode); 1476812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Variable* var = NULL; 147743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 147881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // If a suitable scope exists, then we can statically declare this 147943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // variable and also set its mode. In any case, a Declaration node 148043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will be added to the scope so that the declaration can be added 148143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to the corresponding activation frame at runtime if necessary. 148243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // For instance declarations inside an eval scope need to be added 148343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to the calling function context. 14848e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org // Similarly, strict mode eval scope does not leak variable declarations to 14858e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org // the caller's scope so we declare all locals, too. 14864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (declaration_scope->is_function_scope() || 14871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org declaration_scope->is_strict_or_extended_eval_scope() || 1488f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org declaration_scope->is_block_scope() || 1489bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com declaration_scope->is_module_scope() || 1490355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org declaration_scope->is_global_scope()) { 149181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // Declare the variable in the declaration scope. 1492355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // For the global scope, we have to check for collisions with earlier 1493355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // (i.e., enclosing) global scopes, to maintain the illusion of a single 1494355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // global scope. 1495355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org var = declaration_scope->is_global_scope() 1496355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org ? declaration_scope->Lookup(name) 1497355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org : declaration_scope->LocalLookup(name); 149843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (var == NULL) { 149943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Declare the name. 1500812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org var = declaration_scope->DeclareLocal( 1501bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com name, mode, declaration->initialization(), proxy->interface()); 1502355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org } else if ((mode != VAR || var->mode() != VAR) && 1503355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org (!declaration_scope->is_global_scope() || 1504355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org IsLexicalVariableMode(mode) || 1505355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org IsLexicalVariableMode(var->mode()))) { 15061805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // The name was declared in this scope before; check for conflicting 15071805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // re-declarations. We have a conflict if either of the declarations is 1508355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // not a var (in the global scope, we also have to ignore legacy const for 1509355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // compatibility). There is similar code in runtime.cc in the Declare 15101805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // functions. The function CheckNonConflictingScope checks for conflicting 15111805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // var and let bindings from different scopes whereas this is a check for 15121805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // conflicting declarations within the same scope. This check also covers 1513355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // the special case 15141805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // 15151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // function () { let x; { var x; } } 15161805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // 15171805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // because the var declaration is hoisted to the function scope where 'x' 15181805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // is already bound. 1519355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org ASSERT(IsDeclaredVariableMode(var->mode())); 1520355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org if (is_extended_mode()) { 1521355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // In harmony mode we treat re-declarations as early errors. See 1522355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // ES5 16 for a definition of early errors. 1523355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); 1524355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org const char* elms[2] = { "Variable", *c_string }; 1525355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Vector<const char*> args(elms, 2); 1526355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org ReportMessage("redeclaration", args); 1527355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org *ok = false; 1528355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org return; 152943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1530dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message_string = 15318e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org isolate()->factory()->NewStringFromUtf8(CStrVector("Variable"), 15328e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org TENURED); 1533355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Expression* expression = 15344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org NewThrowTypeError(isolate()->factory()->redeclaration_string(), 1535dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org message_string, name); 1536355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org declaration_scope->SetIllegalRedeclaration(expression); 153743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 153843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 153943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 154043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We add a declaration node for every declaration. The compiler 154143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will only generate code if necessary. In particular, declarations 154243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // for inner local variables that do not represent functions won't 154343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // result in any generated code. 154443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 154543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that we always add an unresolved proxy even if it's not 154643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // used, simply because we don't know in this method (w/o extra 154743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parameters) if the proxy is needed or not. The proxy will be 154843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // bound during variable resolution time unless it was pre-bound 154943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // below. 155043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 155143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WARNING: This will lead to multiple declaration nodes for the 155243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // same variable if it is declared several times. This is not a 155343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // semantic issue as long as we keep the source order, but it may be 155443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // a performance issue since it may lead to repeated 155543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Runtime::DeclareContextSlot() calls. 1556812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org declaration_scope->AddDeclaration(declaration); 155743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1558355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org if (mode == CONST && declaration_scope->is_global_scope()) { 155927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // For global const variables we bind the proxy to a variable. 156043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(resolve); // should be set by all callers 15613e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org Variable::Kind kind = Variable::NORMAL; 156210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org var = new(zone()) Variable( 156310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org declaration_scope, name, mode, true, kind, 156410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org kNeedsInitialization, proxy->interface()); 156527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } else if (declaration_scope->is_eval_scope() && 15661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org declaration_scope->is_classic_mode()) { 156727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // For variable declarations in a non-strict eval scope the proxy is bound 156827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // to a lookup variable to force a dynamic declaration using the 156927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // DeclareContextSlot runtime function. 157027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Variable::Kind kind = Variable::NORMAL; 157110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org var = new(zone()) Variable( 157210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org declaration_scope, name, mode, true, kind, 157310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org declaration->initialization(), proxy->interface()); 157427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org var->AllocateTo(Variable::LOOKUP, -1); 157527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org resolve = true; 157643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 157743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 157843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If requested and we have a local variable, bind the proxy to the variable 157943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // at parse-time. This is used for functions (and consts) declared inside 158043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // statements: the corresponding function (or const) variable must be in the 158143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function scope and not a statement-local scope, e.g. as provided with a 158243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'with' statement: 158343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 158443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // with (obj) { 158543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function f() {} 158643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // } 158743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 158843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // which is translated into: 158943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 159043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // with (obj) { 159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // // in this case this is not: 'var f; f = function () {};' 159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // var f = function () {}; 159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // } 159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 159543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that if 'f' is accessed from inside the 'with' statement, it 159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will be allocated in the context (because we must be able to look 159743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // it up dynamically) but it will also be accessed statically, i.e., 159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // with a context slot index and a context chain length for this 159943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // initialization code. Thus, inside the 'with' statement, we need 160043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // both access to the static and the dynamic context chain; the 160143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // runtime needs to provide both. 1602bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (resolve && var != NULL) { 1603bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com proxy->BindTo(var); 1604bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1605bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_harmony_modules) { 1606bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com bool ok; 1607bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1608bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 1609bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Declare %s\n", var->name()->ToAsciiArray()); 1610bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 16117028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org proxy->interface()->Unify(var->interface(), zone(), &ok); 1612bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (!ok) { 1613bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1614bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 1615bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("DECLARE TYPE ERROR\n"); 1616bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("proxy: "); 1617bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com proxy->interface()->Print(); 1618bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("var: "); 1619bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com var->interface()->Print(); 1620bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1621bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1622bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1)); 1623bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1624bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1625bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 162643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 162743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Language extension which is only enabled for source files loaded 163043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// through the API's extension mechanism. A native function 163143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// declaration is resolved by looking up the function through a 163243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// callback provided by the extension. 163343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseNativeDeclaration(bool* ok) { 1634a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 163543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::FUNCTION, CHECK_OK); 163643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> name = ParseIdentifier(CHECK_OK); 163743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 163843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool done = (peek() == Token::RPAREN); 163943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!done) { 164043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ParseIdentifier(CHECK_OK); 164143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen done = (peek() == Token::RPAREN); 1642fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (!done) { 1643fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org Expect(Token::COMMA, CHECK_OK); 1644fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org } 164543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 164643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 164743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SEMICOLON, CHECK_OK); 164843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure that the function containing the native declaration 165043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // isn't lazily compiled. The extension structures are only 165143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // accessible while parsing the first time not when reparsing 165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // because of lazy compilation. 1653812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org DeclarationScope(VAR)->ForceEagerCompilation(); 165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1240846): It's weird that native function declarations are 165643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // introduced dynamically when we meet their declarations, whereas 1657f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // other functions are set up when entering the surrounding scope. 165828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); 1659812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1660a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewVariableDeclaration(proxy, VAR, top_scope_, pos); 1661812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 1662a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( 1663a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org name, extension_, RelocInfo::kNoPosition); 1664b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewExpressionStatement( 1665b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewAssignment( 1666a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), 1667a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos); 166843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 166943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 167043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1671812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgStatement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { 1672c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // FunctionDeclaration :: 1673c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 1674f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // GeneratorDeclaration :: 1675f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // 'function' '*' Identifier '(' FormalParameterListopt ')' 1676f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // '{' FunctionBody '}' 167743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::FUNCTION, CHECK_OK); 1678a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 1679e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool is_generator = allow_generators() && Check(Token::MUL); 168004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool is_strict_reserved = false; 168104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org Handle<String> name = ParseIdentifierOrStrictReservedWord( 168204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org &is_strict_reserved, CHECK_OK); 1683c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org FunctionLiteral* fun = ParseFunctionLiteral(name, 168404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org is_strict_reserved, 1685f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org is_generator, 1686a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos, 16877c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org FunctionLiteral::DECLARATION, 1688c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org CHECK_OK); 1689c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Even if we're not at the top-level of the global or a function 1690355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // scope, we treat it as such and introduce the function with its 1691c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // initial value upon entering the corresponding scope. 1692355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // In extended mode, a function behaves as a lexical binding, except in the 1693355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // global scope. 1694355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org VariableMode mode = 1695355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; 169628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); 1697812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1698a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_, pos); 1699812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 17007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (names) names->Add(name, zone()); 1701a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewEmptyStatement(RelocInfo::kNoPosition); 170243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 170343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenBlock* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { 17061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); 17074acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 170843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Block :: 170943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '{' Statement* '}' 171043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 171143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that a Block does not introduce a new execution scope! 171243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // (ECMA-262, 3rd, 12.2) 171343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 171443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Construct block expecting 16 statements. 1715a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* result = 1716a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); 1717e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, result); 171843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 171943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::RBRACE) { 172043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* stat = ParseStatement(NULL, CHECK_OK); 17216db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (stat && !stat->IsEmpty()) { 1722400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(stat, zone()); 17236db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 172443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 172543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACE, CHECK_OK); 172643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 172743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 172843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 172943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17304acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.orgBlock* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { 1731f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // The harmony mode uses block elements instead of statements. 1732c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // 1733c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Block :: 1734f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // '{' BlockElement* '}' 1735c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 17364acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Construct block expecting 16 statements. 1737a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* body = 1738a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); 1739394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); 17404acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 17414acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Parse the statements and collect escaping labels. 17424acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Expect(Token::LBRACE, CHECK_OK); 1743394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com block_scope->set_start_position(scanner().location().beg_pos); 1744c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org { BlockState block_state(this, block_scope); 17457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector collector(zone()); 1746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Target target(&this->target_stack_, &collector); 17474acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Target target_body(&this->target_stack_, body); 17484acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 17494acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org while (peek() != Token::RBRACE) { 1750f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Statement* stat = ParseBlockElement(NULL, CHECK_OK); 17514acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (stat && !stat->IsEmpty()) { 1752400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body->AddStatement(stat, zone()); 17534acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 17544acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 17554acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 17564acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Expect(Token::RBRACE, CHECK_OK); 1757394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com block_scope->set_end_position(scanner().location().end_pos); 17581805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org block_scope = block_scope->FinalizeBlockScope(); 1759ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com body->set_scope(block_scope); 1760486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return body; 17614acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org} 17624acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 17634acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 1764b645116853c677aca8a316381b87441ba6004f67danno@chromium.orgBlock* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 1765812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ZoneStringList* names, 1766b645116853c677aca8a316381b87441ba6004f67danno@chromium.org bool* ok) { 176743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableStatement :: 176843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableDeclarations ';' 176943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Handle<String> ignore; 1771f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Block* result = 1772812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); 177343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 177443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 177543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 177643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1777ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1778ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgbool Parser::IsEvalOrArguments(Handle<String> string) { 17794a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return string.is_identical_to(isolate()->factory()->eval_string()) || 17804a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org string.is_identical_to(isolate()->factory()->arguments_string()); 17810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 178243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1783ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 178443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// If the variable declaration declares exactly one non-const 178578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// variable, then *out is set to that variable. In all other cases, 178678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// *out is untouched; in particular, it is the caller's responsibility 178743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to initialize it properly. This mechanism is used for the parsing 178843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// of 'for-in' loops. 1789394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comBlock* Parser::ParseVariableDeclarations( 1790394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com VariableDeclarationContext var_context, 1791394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com VariableDeclarationProperties* decl_props, 1792812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ZoneStringList* names, 1793394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<String>* out, 1794394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool* ok) { 179543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableDeclarations :: 1796394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] 1797394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 1798394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // The ES6 Draft Rev3 specifies the following grammar for const declarations 1799394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 1800394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ConstDeclaration :: 1801394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // const ConstBinding (',' ConstBinding)* ';' 1802394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ConstBinding :: 1803394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Identifier '=' AssignmentExpression 1804394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 1805394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // TODO(ES6): 1806394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ConstBinding :: 1807394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // BindingPattern '=' AssignmentExpression 1808a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org 1809a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 1810b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org VariableMode mode = VAR; 181180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // True if the binding needs initialization. 'let' and 'const' declared 181280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // bindings are created uninitialized by their declaration nodes and 181380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // need initialization. 'var' declared bindings are always initialized 181480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // immediately by their declaration nodes. 181580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org bool needs_init = false; 181643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool is_const = false; 181780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Token::Value init_op = Token::INIT_VAR; 181843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::VAR) { 181943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::VAR); 182043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (peek() == Token::CONST) { 18211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: 18221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 18231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 18241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 18251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // * It is a Syntax Error if the code that matches this production is not 18261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // contained in extended code. 18271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 18281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // However disallowing const in classic mode will break compatibility with 18291b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // existing pages. Therefore we keep allowing const with the old 18301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // non-harmony semantics in classic mode. 183143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::CONST); 18321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org switch (top_scope_->language_mode()) { 18331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org case CLASSIC_MODE: 18341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org mode = CONST; 18351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org init_op = Token::INIT_CONST; 18361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org break; 18371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org case STRICT_MODE: 18381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ReportMessage("strict_const", Vector<const char*>::empty()); 1839394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com *ok = false; 1840394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return NULL; 18411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org case EXTENDED_MODE: 1842f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (var_context == kStatement) { 18431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // In extended mode 'const' declarations are only allowed in source 18441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // element positions. 18451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ReportMessage("unprotected_const", Vector<const char*>::empty()); 18461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org *ok = false; 18471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return NULL; 18481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 18491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org mode = CONST_HARMONY; 18501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org init_op = Token::INIT_CONST_HARMONY; 18519ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 185243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen is_const = true; 185380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org needs_init = true; 1854b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } else if (peek() == Token::LET) { 18551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // ES6 Draft Rev4 section 12.2.1: 18561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 18571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // LetDeclaration : let LetBindingList ; 18581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 18591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // * It is a Syntax Error if the code that matches this production is not 18601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // contained in extended code. 18611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!is_extended_mode()) { 18621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ReportMessage("illegal_let", Vector<const char*>::empty()); 18631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org *ok = false; 18641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return NULL; 18651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 1866b645116853c677aca8a316381b87441ba6004f67danno@chromium.org Consume(Token::LET); 1867f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (var_context == kStatement) { 1868394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Let declarations are only allowed in source element positions. 1869b645116853c677aca8a316381b87441ba6004f67danno@chromium.org ReportMessage("unprotected_let", Vector<const char*>::empty()); 1870b645116853c677aca8a316381b87441ba6004f67danno@chromium.org *ok = false; 1871b645116853c677aca8a316381b87441ba6004f67danno@chromium.org return NULL; 1872b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } 1873b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org mode = LET; 187480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org needs_init = true; 187580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org init_op = Token::INIT_LET; 187643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 187743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); // by current callers 187843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 187943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1880812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Scope* declaration_scope = DeclarationScope(mode); 1881812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1882b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // The scope of a var/const declared variable anywhere inside a function 188343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1884b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // transform a source-level var/const declaration into a (Function) 188543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Scope declaration, and rewrite the source-level initialization into an 188643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // assignment statement. We use a block to collect multiple assignments. 188743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 188843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We mark the block as initializer block because we don't want the 188943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // rewriter to add a '.result' assignment to such a block (to get compliant 189043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // behavior for code such as print(eval('var x = 7')), and for cosmetic 189143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // reasons when pretty-printing. Also, unless an assignment (initialization) 189243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is inside an initializer block, it is ignored. 189343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 189443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create new block with one expected declaration. 1895a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* block = factory()->NewBlock(NULL, 1, true, pos); 189643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int nvars = 0; // the number of variables declared 18974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Handle<String> name; 189843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen do { 189965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Enter(); 190065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 190143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse variable name. 190243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (nvars > 0) Consume(Token::COMMA); 19034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org name = ParseIdentifier(CHECK_OK); 190465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushVariableName(name); 190543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19060a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Strict mode variables may not be named eval or arguments 19071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) { 19080a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org ReportMessage("strict_var_name", Vector<const char*>::empty()); 19090a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org *ok = false; 19100a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return NULL; 19110a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 19120a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 191343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Declare variable. 191443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that we *always* must treat the initial value via a separate init 191543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // assignment for variables and constants because the value must be assigned 191643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // when the variable is encountered in the source. But the variable/constant 191743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is declared (and set to 'undefined') upon entering the function within 191843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // which the variable or constant is declared. Only function variables have 191943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // an initial value in the declaration (because they are initialized upon 192043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // entering the function). 192143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 192243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we have a const declaration, in an inner scope, the proxy is always 192343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // bound to the declared variable (independent of possibly surrounding with 192443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // statements). 1925394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // For let/const declarations in harmony mode, we can also immediately 1926394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // pre-resolve the proxy because it resides in the same scope as the 1927394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // declaration. 192828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org Interface* interface = 192928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org is_const ? Interface::NewConst() : Interface::NewValue(); 193028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org VariableProxy* proxy = NewUnresolved(name, mode, interface); 1931812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1932a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos); 1933812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, mode != VAR, CHECK_OK); 193443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen nvars++; 19354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { 19367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ReportMessageAt(scanner().location(), "too_many_variables", 19377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Vector<const char*>::empty()); 19387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org *ok = false; 19397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return NULL; 19407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 19417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (names) names->Add(name, zone()); 194243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 194343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse initialization expression if present and/or needed. A 194443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration of the form: 194543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 194643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // var v = x; 194743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 194843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is syntactic sugar for: 194943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 195043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // var v; v = x; 195143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 19524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // In particular, we need to re-lookup 'v' (in top_scope_, not 19534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // declaration_scope) as it may be a different 'v' than the 'v' in the 19544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // declaration (e.g., if we are inside a 'with' statement or 'catch' 19554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // block). 195643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 195743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // However, note that const declarations are different! A const 195843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration of the form: 195943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 196043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // const c = x; 196143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 196243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is *not* syntactic sugar for: 196343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 196443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // const c; c = x; 196543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 196643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The "variable" c initialized to x is the same as the declared 196743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // one - there is no re-lookup (see the last parameter of the 196843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Declare() call above). 196943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Scope* initialization_scope = is_const ? declaration_scope : top_scope_; 197143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* value = NULL; 1972a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = -1; 1973394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Harmony consts have non-optional initializers. 1974394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { 197543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::ASSIGN, CHECK_OK); 1976a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos = position(); 1977b645116853c677aca8a316381b87441ba6004f67danno@chromium.org value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 197865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Don't infer if it is "a = function(){...}();"-like expression. 197904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (fni_ != NULL && 198004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org value->AsCall() == NULL && 198104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org value->AsCallNew() == NULL) { 198204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org fni_->Infer(); 1983c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 1984c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fni_->RemoveLastFunction(); 198504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 1986394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (decl_props != NULL) *decl_props = kHasInitializers; 198743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 198843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1989c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Record the end position of the initializer. 1990c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org if (proxy->var() != NULL) { 1991a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org proxy->var()->set_initializer_position(position()); 1992c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org } 1993c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 199480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Make sure that 'const x' and 'let x' initialize 'x' to undefined. 199580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org if (value == NULL && needs_init) { 1996a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org value = GetLiteralUndefined(position()); 199743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 199843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 199943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Global variable declarations must be compiled in a specific 200043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // way. When the script containing the global variable declaration 200143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is entered, the global variable must be declared, so that if it 2002ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // doesn't exist (on the global object itself, see ES5 errata) it 200343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // gets created with an initial undefined value. This is handled 200443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // by the declarations part of the function representing the 200543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // top-level global code; see Runtime::DeclareGlobalVariable. If 200643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // it already exists (in the object or in a prototype), it is 200743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // *not* touched until the variable declaration statement is 200843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // executed. 200943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 201043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Executing the variable declaration statement will always 201143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // guarantee to give the global object a "local" variable; a 201243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // variable defined in the global object and not in any 201343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // prototype. This way, global variable declarations can shadow 201443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // properties in the prototype chain, but only after the variable 201543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration statement has been executed. This is important in 201643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // browsers where the global object (window) has lots of 201743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // properties defined in prototype objects. 2018355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org if (initialization_scope->is_global_scope() && 2019355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org !IsLexicalVariableMode(mode)) { 202043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute the arguments for the runtime call. 20217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Expression*>* arguments = 20227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<Expression*>(3, zone()); 2023c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // We have at least 1 parameter. 2024a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org arguments->Add(factory()->NewLiteral(name, pos), zone()); 202543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CallRuntime* initialize; 20269ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 202743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (is_const) { 20287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org arguments->Add(value, zone()); 20299ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org value = NULL; // zap the value to avoid the unnecessary assignment 20309ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 20319ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Construct the call to Runtime_InitializeConstGlobal 20329ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // and add it to the initialization statement block. 20339ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Note that the function does different things depending on 20349ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // the number of arguments (1 or 2). 2035b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org initialize = factory()->NewCallRuntime( 20364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->InitializeConstGlobal_string(), 2037b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org Runtime::FunctionForId(Runtime::kInitializeConstGlobal), 2038a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org arguments, pos); 203943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 20409ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Add strict mode. 20419ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // We may want to pass singleton to avoid Literal allocations. 20421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org LanguageMode language_mode = initialization_scope->language_mode(); 2043a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org arguments->Add(factory()->NewNumberLiteral(language_mode, pos), zone()); 20449ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 20459ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Be careful not to assign a value to the global variable if 20469ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // we're in a with. The initialization value should not 20479ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // necessarily be stored in the global object in that case, 20489ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // which is why we need to generate a separate assignment node. 20499ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org if (value != NULL && !inside_with()) { 20507028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org arguments->Add(value, zone()); 20519ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org value = NULL; // zap the value to avoid the unnecessary assignment 20529ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 20539ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 20549ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Construct the call to Runtime_InitializeVarGlobal 20559ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // and add it to the initialization statement block. 20569ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Note that the function does different things depending on 20579ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // the number of arguments (2 or 3). 2058b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org initialize = factory()->NewCallRuntime( 20594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->InitializeVarGlobal_string(), 2060b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org Runtime::FunctionForId(Runtime::kInitializeVarGlobal), 2061a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org arguments, pos); 206243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 20639ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 2064a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org block->AddStatement( 2065a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), 2066a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org zone()); 206727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } else if (needs_init) { 206827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // Constant initializations always assign to the declared constant which 206927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // is always at the function scope level. This is only relevant for 207027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // dynamically looked-up variables and constants (the start context for 207127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // constant lookups is always the function context, while it is the top 207227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // context for var declared variables). Sigh... 207327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // For 'let' and 'const' declared variables in harmony mode the 207427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // initialization also always assigns to the declared variable. 207527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(proxy != NULL); 207627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(proxy->var() != NULL); 207727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(value != NULL); 207827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Assignment* assignment = 2079a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewAssignment(init_op, proxy, value, pos); 2080a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org block->AddStatement( 2081a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), 2082a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org zone()); 208327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org value = NULL; 208443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 208543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2086486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Add an assignment node to the initialization statement block if we still 208727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // have a pending initialization value. 208843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (value != NULL) { 208927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(mode == VAR); 209027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // 'var' initializations are simply assignments (with all the consequences 209127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // if they are inside a 'with' statement - they may change a 'with' object 209227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // property). 2093b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org VariableProxy* proxy = 209428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org initialization_scope->NewUnresolved(factory(), name, interface); 2095c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Assignment* assignment = 2096a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewAssignment(init_op, proxy, value, pos); 2097a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org block->AddStatement( 2098a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), 2099a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org zone()); 210043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 210165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 210265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Leave(); 210343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } while (peek() == Token::COMMA); 210443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // If there was a single non-const declaration, return it in the output 21064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // parameter for possible use by for/in. 21074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (nvars == 1 && !is_const) { 21084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org *out = name; 210943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 211043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 211143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return block; 211243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 211343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 211443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 211543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { 211643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(!label.is_null()); 211743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (labels != NULL) 211843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = labels->length(); i-- > 0; ) 211943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (labels->at(i).is_identical_to(label)) 212043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 212143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 212243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 212343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 212443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 212543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 212643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, 212743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* ok) { 212843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ExpressionStatement | LabelledStatement :: 212943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expression ';' 213043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Identifier ':' Statement 2131a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 213283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org bool starts_with_idenfifier = peek_any_identifier(); 213343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expr = ParseExpression(true, CHECK_OK); 21347b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && 213543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen expr->AsVariableProxy() != NULL && 213643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen !expr->AsVariableProxy()->is_this()) { 21374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Expression is a single identifier, and not, e.g., a parenthesized 21384a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // identifier. 213943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen VariableProxy* var = expr->AsVariableProxy(); 214043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> label = var->name(); 214143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1240780): We don't check for redeclaration of labels 214243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // during preparsing since keeping track of the set of active 214343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // labels requires nontrivial changes to the way scopes are 214443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // structured. However, these are probably changes we want to 214543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // make later anyway so we should go back and fix this then. 2146fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { 214783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS); 2148fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org const char* elms[2] = { "Label", *c_string }; 2149fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org Vector<const char*> args(elms, 2); 2150fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org ReportMessage("redeclaration", args); 2151fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org *ok = false; 2152fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org return NULL; 215343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 21547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (labels == NULL) { 21557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org labels = new(zone()) ZoneStringList(4, zone()); 21567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 21577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org labels->Add(label, zone()); 2158fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // Remove the "ghost" variable that turned out to be a label 2159fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // from the top scope. This way, we don't try to resolve it 2160fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // during the scope processing. 2161fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org top_scope_->RemoveUnresolved(var); 216243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COLON, CHECK_OK); 216343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return ParseStatement(labels, ok); 216443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 216543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21667b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // If we have an extension, we allow a native function declaration. 21677b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // A native function declaration starts with "native function" with 21687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // no line-terminator between the two words. 21697b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (extension_ != NULL && 21707b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org peek() == Token::FUNCTION && 2171df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org !scanner().HasAnyLineTerminatorBeforeNext() && 21727b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org expr != NULL && 21737b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org expr->AsVariableProxy() != NULL && 21747b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org expr->AsVariableProxy()->name()->Equals( 21754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->heap()->native_string()) && 21767b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org !scanner().literal_contains_escapes()) { 21777b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org return ParseNativeDeclaration(ok); 21787b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 21797b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 2180a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org // Parsed expression statement, or the context-sensitive 'module' keyword. 2181a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org // Only expect semicolon in the former case. 2182a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org if (!FLAG_harmony_modules || 2183a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org peek() != Token::IDENTIFIER || 2184a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org scanner().HasAnyLineTerminatorBeforeNext() || 2185a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org expr->AsVariableProxy() == NULL || 2186a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org !expr->AsVariableProxy()->name()->Equals( 21874a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->heap()->module_string()) || 2188a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org scanner().literal_contains_escapes()) { 2189a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org ExpectSemicolon(CHECK_OK); 2190a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 2191a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewExpressionStatement(expr, pos); 219243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 219343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 219443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 219543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenIfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { 219643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IfStatement :: 219743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'if' '(' Expression ')' Statement ('else' Statement)? 219843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2199a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 220043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::IF, CHECK_OK); 220143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 220243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* condition = ParseExpression(true, CHECK_OK); 220343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 220443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* then_statement = ParseStatement(labels, CHECK_OK); 220543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* else_statement = NULL; 220643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::ELSE) { 220743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 220843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen else_statement = ParseStatement(labels, CHECK_OK); 2209fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org } else { 2210a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 221143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2212a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewIfStatement( 2213a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org condition, then_statement, else_statement, pos); 221443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 221543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 221643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 221743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseContinueStatement(bool* ok) { 221843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ContinueStatement :: 221943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'continue' Identifier? ';' 222043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2221a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 222243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::CONTINUE, CHECK_OK); 222368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org Handle<String> label = Handle<String>::null(); 222443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value tok = peek(); 2225df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org if (!scanner().HasAnyLineTerminatorBeforeNext() && 22269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 222743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen label = ParseIdentifier(CHECK_OK); 222843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 222943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IterationStatement* target = NULL; 2230fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org target = LookupContinueTarget(label, CHECK_OK); 2231fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (target == NULL) { 2232c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Illegal continue statement. 2233c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org const char* message = "illegal_continue"; 2234c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Vector<Handle<String> > args; 2235c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (!label.is_null()) { 2236c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org message = "unknown_label"; 2237c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org args = Vector<Handle<String> >(&label, 1); 2238c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 2239c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ReportMessageAt(scanner().location(), message, args); 2240c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org *ok = false; 2241c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return NULL; 224243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 224343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 2244a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewContinueStatement(target, pos); 224543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 224643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 224743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 224843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { 224943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // BreakStatement :: 225043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'break' Identifier? ';' 225143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2252a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 225343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::BREAK, CHECK_OK); 225443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> label; 225543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value tok = peek(); 2256df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org if (!scanner().HasAnyLineTerminatorBeforeNext() && 22579258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 225843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen label = ParseIdentifier(CHECK_OK); 225943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 22603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Parse labeled break statements that target themselves into 226143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // empty statements, e.g. 'l1: l2: l3: break l2;' 226243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!label.is_null() && ContainsLabel(labels, label)) { 2263b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org ExpectSemicolon(CHECK_OK); 2264a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewEmptyStatement(pos); 226543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 226643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakableStatement* target = NULL; 2267fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org target = LookupBreakTarget(label, CHECK_OK); 2268fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (target == NULL) { 2269c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Illegal break statement. 2270c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org const char* message = "illegal_break"; 2271c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Vector<Handle<String> > args; 2272c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (!label.is_null()) { 2273c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org message = "unknown_label"; 2274c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org args = Vector<Handle<String> >(&label, 1); 2275c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 2276c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ReportMessageAt(scanner().location(), message, args); 2277c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org *ok = false; 2278c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return NULL; 227943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 228043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 2281a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewBreakStatement(target, pos); 228243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 228343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 228443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 228543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseReturnStatement(bool* ok) { 228643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ReturnStatement :: 228743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'return' Expression? ';' 228843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2289a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org // Consume the return token. It is necessary to do that before 229043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // reporting any errors on it, because of the way errors are 229143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // reported (underlining). 229243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RETURN, CHECK_OK); 2293a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 229443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 229564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Token::Value tok = peek(); 229664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Statement* result; 229777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Expression* return_value; 229864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (scanner().HasAnyLineTerminatorBeforeNext() || 229964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org tok == Token::SEMICOLON || 230064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org tok == Token::RBRACE || 230164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org tok == Token::EOS) { 2302a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return_value = GetLiteralUndefined(position()); 230364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 230477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org return_value = ParseExpression(true, CHECK_OK); 230577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 230677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org ExpectSemicolon(CHECK_OK); 230777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (is_generator()) { 230877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Expression* generator = factory()->NewVariableProxy( 230977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org current_function_state_->generator_object_variable()); 231077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Expression* yield = factory()->NewYield( 2311a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org generator, return_value, Yield::FINAL, pos); 2312a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewExpressionStatement(yield, pos); 231377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 2314a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewReturnStatement(return_value, pos); 231564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 231664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 231743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // An ECMAScript program is considered syntactically incorrect if it 231843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // contains a return statement that is not within the body of a 231943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function. See ECMA-262, section 12.9, page 67. 232043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 232143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // To be consistent with KJS we report the syntax error at runtime. 23224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Scope* declaration_scope = top_scope_->DeclarationScope(); 23234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (declaration_scope->is_global_scope() || 23244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org declaration_scope->is_eval_scope()) { 2325dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message = isolate()->factory()->illegal_return_string(); 2326dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Expression* throw_error = 2327dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org NewThrowSyntaxError(message, Handle<Object>::null()); 2328a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewExpressionStatement(throw_error, pos); 232943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 233064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org return result; 233143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 233243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 233343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 233443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { 233543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WithStatement :: 233643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'with' '(' Expression ')' Statement 233743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 233843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::WITH, CHECK_OK); 2339a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 23400a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 23411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode()) { 23420a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org ReportMessage("strict_mode_with", Vector<const char*>::empty()); 23430a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org *ok = false; 23440a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return NULL; 23450a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 23460a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 234743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 234843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expr = ParseExpression(true, CHECK_OK); 234943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 235043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23514acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org top_scope_->DeclarationScope()->RecordWithStatement(); 2352394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); 2353394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Statement* stmt; 2354c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org { BlockState block_state(this, with_scope); 2355394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com with_scope->set_start_position(scanner().peek_location().beg_pos); 2356394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com stmt = ParseStatement(labels, CHECK_OK); 2357394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com with_scope->set_end_position(scanner().location().end_pos); 2358394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 2359a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewWithStatement(with_scope, expr, stmt, pos); 236043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 236143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 236243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 236343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenCaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { 236443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // CaseClause :: 236543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'case' Expression ':' Statement* 236643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'default' ':' Statement* 236743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 236843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* label = NULL; // NULL expression indicates default case 236943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::CASE) { 237043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::CASE, CHECK_OK); 237143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen label = ParseExpression(true, CHECK_OK); 237243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 237343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::DEFAULT, CHECK_OK); 237443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (*default_seen_ptr) { 237543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReportMessage("multiple_defaults_in_switch", 237643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Vector<const char*>::empty()); 237743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 237843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 237943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 238043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *default_seen_ptr = true; 238143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 238243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COLON, CHECK_OK); 2383a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 23847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Statement*>* statements = 23857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<Statement*>(5, zone()); 238643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::CASE && 238743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen peek() != Token::DEFAULT && 238843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen peek() != Token::RBRACE) { 238943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* stat = ParseStatement(NULL, CHECK_OK); 23907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org statements->Add(stat, zone()); 239143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 239243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2393a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewCaseClause(label, statements, pos); 239443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 239543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 239643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 239743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenSwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, 239843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* ok) { 239943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // SwitchStatement :: 240043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'switch' '(' Expression ')' '{' CaseClause* '}' 240143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2402a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org SwitchStatement* statement = 2403a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewSwitchStatement(labels, peek_position()); 2404e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, statement); 240543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 240643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SWITCH, CHECK_OK); 240743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 240843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* tag = ParseExpression(true, CHECK_OK); 240943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 241043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 241143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool default_seen = false; 24127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone()); 241343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 241443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::RBRACE) { 241543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); 24167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org cases->Add(clause, zone()); 241743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 241843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACE, CHECK_OK); 241943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2420fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (statement) statement->Initialize(tag, cases); 242143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return statement; 242243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 242343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 242443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 242543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseThrowStatement(bool* ok) { 242643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ThrowStatement :: 242743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'throw' Expression ';' 242843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 242943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::THROW, CHECK_OK); 2430a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 2431df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org if (scanner().HasAnyLineTerminatorBeforeNext()) { 243243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReportMessage("newline_after_throw", Vector<const char*>::empty()); 243343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 243443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 243543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 243643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* exception = ParseExpression(true, CHECK_OK); 243743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 243843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2439a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewExpressionStatement( 2440a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewThrow(exception, pos), pos); 244143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 244243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 244343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 244443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTryStatement* Parser::ParseTryStatement(bool* ok) { 244543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TryStatement :: 244643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'try' Block Catch 244743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'try' Block Finally 244843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'try' Block Catch Finally 244943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 245043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Catch :: 245143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'catch' '(' Identifier ')' Block 245243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 245343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Finally :: 245443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'finally' Block 245543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 245643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::TRY, CHECK_OK); 2457a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 245843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector try_collector(zone()); 246043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Block* try_block; 246143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24626d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org { Target target(&this->target_stack_, &try_collector); 246343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen try_block = ParseBlock(NULL, CHECK_OK); 246443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 246543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 246643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value tok = peek(); 246743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tok != Token::CATCH && tok != Token::FINALLY) { 246843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); 246943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 247043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 247143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 247243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 247343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we can break out from the catch block and there is a finally block, 24746d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // then we will need to collect escaping targets from the catch 24756d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // block. Since we don't know yet if there will be a finally block, we 24766d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // always collect the targets. 24777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector catch_collector(zone()); 24784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Scope* catch_scope = NULL; 24794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Variable* catch_variable = NULL; 24806d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Block* catch_block = NULL; 24816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Handle<String> name; 248243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tok == Token::CATCH) { 248343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::CATCH); 248443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 248543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 2486394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com catch_scope = NewScope(top_scope_, CATCH_SCOPE); 2487394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com catch_scope->set_start_position(scanner().location().beg_pos); 24886d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org name = ParseIdentifier(CHECK_OK); 24890a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 24901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) { 24910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org ReportMessage("strict_catch_variable", Vector<const char*>::empty()); 24920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org *ok = false; 24930a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return NULL; 24940a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 24950a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 249643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 249743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 249843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::LBRACE) { 24994acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Target target(&this->target_stack_, &catch_collector); 25001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org VariableMode mode = is_extended_mode() ? LET : VAR; 2501c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org catch_variable = 2502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org catch_scope->DeclareLocal(name, mode, kCreatedInitialized); 25034acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 2504c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org BlockState block_state(this, catch_scope); 250555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org catch_block = ParseBlock(NULL, CHECK_OK); 250643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 250743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 250843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2509394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com catch_scope->set_end_position(scanner().location().end_pos); 251043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tok = peek(); 251143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 251243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25136d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Block* finally_block = NULL; 25146d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org if (tok == Token::FINALLY || catch_block == NULL) { 251543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::FINALLY); 251643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen finally_block = ParseBlock(NULL, CHECK_OK); 251743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 251843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 251943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Simplify the AST nodes by converting: 25206d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // 'try B0 catch B1 finally B2' 252143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to: 25226d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // 'try { try B0 catch B1 } finally B2' 252343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2524fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (catch_block != NULL && finally_block != NULL) { 25254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // If we have both, create an inner try/catch. 25264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(catch_scope != NULL && catch_variable != NULL); 252704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int index = current_function_state_->NextHandlerIndex(); 2528b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org TryCatchStatement* statement = factory()->NewTryCatchStatement( 2529a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org index, try_block, catch_scope, catch_variable, catch_block, 2530a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org RelocInfo::kNoPosition); 25316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org statement->set_escaping_targets(try_collector.targets()); 2532a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 2533400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org try_block->AddStatement(statement, zone()); 25344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org catch_block = NULL; // Clear to indicate it's been handled. 253543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 253643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 253743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TryStatement* result = NULL; 2538fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (catch_block != NULL) { 2539fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org ASSERT(finally_block == NULL); 25404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(catch_scope != NULL && catch_variable != NULL); 254104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int index = current_function_state_->NextHandlerIndex(); 2542b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewTryCatchStatement( 2543a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org index, try_block, catch_scope, catch_variable, catch_block, pos); 2544fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org } else { 2545fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org ASSERT(finally_block != NULL); 254604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int index = current_function_state_->NextHandlerIndex(); 2547a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewTryFinallyStatement( 2548a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org index, try_block, finally_block, pos); 25496d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // Combine the jump targets of the try block and the possible catch block. 25507028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org try_collector.targets()->AddAll(*catch_collector.targets(), zone()); 255143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 255243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25536d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org result->set_escaping_targets(try_collector.targets()); 255443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 255543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 255643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 255743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25589d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comDoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, 25599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com bool* ok) { 256043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // DoStatement :: 256143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'do' Statement 'while' '(' Expression ')' ';' 256243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2563a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org DoWhileStatement* loop = 2564a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewDoWhileStatement(labels, peek_position()); 2565e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 256643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 256743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::DO, CHECK_OK); 256843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 256943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::WHILE, CHECK_OK); 257043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 2571c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 257243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* cond = ParseExpression(true, CHECK_OK); 257343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 257443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 257543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Allow do-statements to be terminated with and without 257643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // semi-colons. This allows code such as 'do;while(0)return' to 257743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parse, which would not be the case if we had used the 257843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ExpectSemicolon() functionality here. 257943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 258043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25819d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (loop != NULL) loop->Initialize(cond, body); 258243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return loop; 258343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 258443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 258543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25869d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comWhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { 258743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WhileStatement :: 258843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'while' '(' Expression ')' Statement 258943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2590a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); 2591e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 259243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 259343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::WHILE, CHECK_OK); 259443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 259543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* cond = ParseExpression(true, CHECK_OK); 259643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 259743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 259843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25999d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (loop != NULL) loop->Initialize(cond, body); 260043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return loop; 260143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 260243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 260343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 260441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgbool Parser::CheckInOrOf(bool accept_OF, 260541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ForEachStatement::VisitMode* visit_mode) { 26061fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org if (Check(Token::IN)) { 26071fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org *visit_mode = ForEachStatement::ENUMERATE; 26081fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return true; 260941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } else if (allow_for_of() && accept_OF && 261041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org CheckContextualKeyword(CStrVector("of"))) { 26111fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org *visit_mode = ForEachStatement::ITERATE; 26121fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return true; 26131fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26141fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return false; 26151fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org} 26161fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26171fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26181fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid Parser::InitializeForEachStatement(ForEachStatement* stmt, 26191fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* each, 26201fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* subject, 26211fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Statement* body) { 26221fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForOfStatement* for_of = stmt->AsForOfStatement(); 26231fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26241fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org if (for_of != NULL) { 26251fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Factory* heap_factory = isolate()->factory(); 2626e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Variable* iterator = top_scope_->DeclarationScope()->NewTemporary( 2627e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org heap_factory->dot_iterator_string()); 2628e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Variable* result = top_scope_->DeclarationScope()->NewTemporary( 2629e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org heap_factory->dot_result_string()); 26301fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26311fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* assign_iterator; 26321fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* next_result; 26331fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_done; 26341fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* assign_each; 26351fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26361fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // var iterator = iterable; 26371fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org { 26381fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 26391fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org assign_iterator = factory()->NewAssignment( 26401fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); 26411fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26421fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26431fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // var result = iterator.next(); 26441fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org { 26451fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 2646a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Expression* next_literal = factory()->NewLiteral( 2647a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org heap_factory->next_string(), RelocInfo::kNoPosition); 26481fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* next_property = factory()->NewProperty( 26491fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org iterator_proxy, next_literal, RelocInfo::kNoPosition); 26501fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ZoneList<Expression*>* next_arguments = 26511fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org new(zone()) ZoneList<Expression*>(0, zone()); 26521fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* next_call = factory()->NewCall( 26531fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org next_property, next_arguments, RelocInfo::kNoPosition); 26541fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_proxy = factory()->NewVariableProxy(result); 26551fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org next_result = factory()->NewAssignment( 26561fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); 26571fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26581fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26591fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // result.done 26601fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org { 2661a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Expression* done_literal = factory()->NewLiteral( 2662a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org heap_factory->done_string(), RelocInfo::kNoPosition); 26631fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_proxy = factory()->NewVariableProxy(result); 26641fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org result_done = factory()->NewProperty( 26651fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org result_proxy, done_literal, RelocInfo::kNoPosition); 26661fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26671fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26681fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // each = result.value 26691fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org { 2670a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Expression* value_literal = factory()->NewLiteral( 2671a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org heap_factory->value_string(), RelocInfo::kNoPosition); 26721fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_proxy = factory()->NewVariableProxy(result); 26731fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_value = factory()->NewProperty( 26741fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org result_proxy, value_literal, RelocInfo::kNoPosition); 26751fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org assign_each = factory()->NewAssignment( 26761fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); 26771fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26781fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26791fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org for_of->Initialize(each, subject, body, 26801fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org assign_iterator, next_result, result_done, assign_each); 26811fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } else { 26821fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org stmt->Initialize(each, subject, body); 26831fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26841fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org} 26851fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26861fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 268743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { 268843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ForStatement :: 268943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 269043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2691a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 269243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* init = NULL; 269343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2694394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Create an in-between scope for let-bound iteration variables. 2695394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Scope* saved_scope = top_scope_; 2696394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); 2697394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com top_scope_ = for_scope; 2698394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 269943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::FOR, CHECK_OK); 270043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 2701394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope->set_start_position(scanner().location().beg_pos); 270243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::SEMICOLON) { 270343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::VAR || peek() == Token::CONST) { 270428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org bool is_const = peek() == Token::CONST; 27054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Handle<String> name; 270641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org VariableDeclarationProperties decl_props = kHasNoInitializers; 270743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Block* variable_statement = 270841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, 270941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org CHECK_OK); 271041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org bool accept_OF = decl_props == kHasNoInitializers; 27111fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement::VisitMode mode; 27124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 271341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { 271428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org Interface* interface = 271528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org is_const ? Interface::NewConst() : Interface::NewValue(); 2716a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ForEachStatement* loop = 2717a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewForEachStatement(mode, labels, pos); 2718e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 271943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 272043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* enumerable = ParseExpression(true, CHECK_OK); 272143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 272243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 272333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org VariableProxy* each = 272433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org top_scope_->NewUnresolved(factory(), name, interface); 272543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 27261fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org InitializeForEachStatement(loop, each, enumerable, body); 2727a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* result = 2728a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); 2729400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(variable_statement, zone()); 2730400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(loop, zone()); 2731394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com top_scope_ = saved_scope; 2732394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope->set_end_position(scanner().location().end_pos); 2733394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope = for_scope->FinalizeBlockScope(); 2734394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(for_scope == NULL); 2735fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // Parsed for-in loop w/ variable/const declaration. 2736fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org return result; 273743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 273843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen init = variable_statement; 273943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2740394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else if (peek() == Token::LET) { 2741394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<String> name; 2742394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com VariableDeclarationProperties decl_props = kHasNoInitializers; 2743394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Block* variable_statement = 2744812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, 2745812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org CHECK_OK); 2746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool accept_IN = !name.is_null() && decl_props != kHasInitializers; 274741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org bool accept_OF = decl_props == kHasNoInitializers; 27481fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement::VisitMode mode; 27491fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 275041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (accept_IN && CheckInOrOf(accept_OF, &mode)) { 2751394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Rewrite a for-in statement of the form 2752394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2753394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // for (let x in e) b 2754394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2755394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // into 2756394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2757394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // <let x' be a temporary variable> 2758394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // for (x' in e) { 2759394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // let x; 2760394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // x = x'; 2761394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // b; 2762394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // } 2763394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2764394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // TODO(keuchel): Move the temporary variable to the block scope, after 2765394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // implementing stack allocated block scoped variables. 276633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Factory* heap_factory = isolate()->factory(); 276733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Handle<String> tempstr = 27684a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org heap_factory->NewConsString(heap_factory->dot_for_string(), name); 27694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<String> tempname = heap_factory->InternalizeString(tempstr); 277033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); 2771b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 2772a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ForEachStatement* loop = 2773a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewForEachStatement(mode, labels, pos); 2774394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Target target(&this->target_stack_, loop); 2775394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 277633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // The expression does not see the loop variable. 277733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org top_scope_ = saved_scope; 2778394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Expression* enumerable = ParseExpression(true, CHECK_OK); 277933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org top_scope_ = for_scope; 2780394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Expect(Token::RPAREN, CHECK_OK); 278143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 278233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org VariableProxy* each = 278333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); 2784394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Statement* body = ParseStatement(NULL, CHECK_OK); 2785a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* body_block = 2786a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 2787b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org Assignment* assignment = factory()->NewAssignment( 2788b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); 2789a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Statement* assignment_statement = factory()->NewExpressionStatement( 2790a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org assignment, RelocInfo::kNoPosition); 2791400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body_block->AddStatement(variable_statement, zone()); 2792400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body_block->AddStatement(assignment_statement, zone()); 2793400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body_block->AddStatement(body, zone()); 27941fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); 2795394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com top_scope_ = saved_scope; 2796394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope->set_end_position(scanner().location().end_pos); 2797394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope = for_scope->FinalizeBlockScope(); 2798ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com body_block->set_scope(for_scope); 2799394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Parsed for-in loop w/ let declaration. 2800394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return loop; 2801394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2802394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 2803394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com init = variable_statement; 2804394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 280543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 280643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expression = ParseExpression(false, CHECK_OK); 28071fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement::VisitMode mode; 280841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org bool accept_OF = expression->AsVariableProxy(); 28091fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 281041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (CheckInOrOf(accept_OF, &mode)) { 2811c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Signal a reference error if the expression is an invalid 2812c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // left-hand side expression. We could report this as a syntax 2813c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // error here but for compatibility with JSC we choose to report 2814c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // the error at runtime. 281543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (expression == NULL || !expression->IsValidLeftHandSide()) { 2816dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message = 28174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->invalid_lhs_in_for_in_string(); 2818dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org expression = NewThrowReferenceError(message); 281943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2820a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ForEachStatement* loop = 2821a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewForEachStatement(mode, labels, pos); 2822e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 282343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 282443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* enumerable = ParseExpression(true, CHECK_OK); 282543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 282643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 282743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 28281fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org InitializeForEachStatement(loop, expression, enumerable, body); 2829394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com top_scope_ = saved_scope; 2830394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope->set_end_position(scanner().location().end_pos); 2831394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope = for_scope->FinalizeBlockScope(); 2832394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(for_scope == NULL); 283343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parsed for-in loop. 283443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return loop; 283543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 283643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 2837a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org init = factory()->NewExpressionStatement( 2838a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org expression, RelocInfo::kNoPosition); 283943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 284043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 284143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 284243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 284343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Standard 'for' loop 2844a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ForStatement* loop = factory()->NewForStatement(labels, pos); 2845e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 284643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 284743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parsed initializer at this point. 284843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SEMICOLON, CHECK_OK); 284943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 285043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* cond = NULL; 285143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::SEMICOLON) { 285243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cond = ParseExpression(true, CHECK_OK); 285343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 285443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SEMICOLON, CHECK_OK); 285543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 285643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* next = NULL; 285743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::RPAREN) { 285843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* exp = ParseExpression(true, CHECK_OK); 2859a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition); 286043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 286143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 286243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 286343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 2864394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com top_scope_ = saved_scope; 2865394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope->set_end_position(scanner().location().end_pos); 2866394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope = for_scope->FinalizeBlockScope(); 2867394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (for_scope != NULL) { 2868394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Rewrite a for statement of the form 2869394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2870394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // for (let x = i; c; n) b 2871394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2872394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // into 2873394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2874394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // { 2875394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // let x = i; 2876394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // for (; c; n) b 2877394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // } 2878394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(init != NULL); 2879a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Block* result = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); 2880400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(init, zone()); 2881400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(loop, zone()); 2882ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com result->set_scope(for_scope); 28831fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org loop->Initialize(NULL, cond, next, body); 2884394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return result; 2885394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 28861fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org loop->Initialize(init, cond, next, body); 2887394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return loop; 2888394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 288943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 289043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 289143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 289243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence = 1 289343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseExpression(bool accept_IN, bool* ok) { 289443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expression :: 289543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // AssignmentExpression 289643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expression ',' AssignmentExpression 289743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 289843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); 289943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() == Token::COMMA) { 290043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COMMA, CHECK_OK); 2901a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 290243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 2903a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 290443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 290543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 290643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 290743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 290843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 290943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence = 2 291043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { 291143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // AssignmentExpression :: 291243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ConditionalExpression 2913f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // YieldExpression 291443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LeftHandSideExpression AssignmentOperator AssignmentExpression 291543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2916f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (peek() == Token::YIELD && is_generator()) { 2917f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return ParseYieldExpression(ok); 2918f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } 2919f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 292065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Enter(); 292143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); 292243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 292343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!Token::IsAssignmentOp(peek())) { 292465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Leave(); 292543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parsed conditional expression only (no assignment). 292643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return expression; 292743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 292843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2929c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Signal a reference error if the expression is an invalid left-hand 2930c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // side expression. We could report this as a syntax error here but 2931c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // for compatibility with JSC we choose to report the error at 2932c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // runtime. 2933a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // TODO(ES5): Should change parsing for spec conformance. 293443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (expression == NULL || !expression->IsValidLeftHandSide()) { 2935dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message = 29364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->invalid_lhs_in_assignment_string(); 2937dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org expression = NewThrowReferenceError(message); 293843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 293943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode()) { 2941378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Assignment to eval or arguments is disallowed in strict mode. 2942378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); 2943378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 294464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MarkAsLValue(expression); 2945378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 294643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value op = Next(); // Get assignment operator. 2947a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 294843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 294943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 295043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1231235): We try to estimate the set of properties set by 295143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // constructors. We define a new property whenever there is an 295243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // assignment to a property of 'this'. We should probably only add 295343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // properties if we haven't seen them before. Otherwise we'll 295443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // probably overestimate the number of properties. 295543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Property* property = expression ? expression->AsProperty() : NULL; 295643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (op == Token::ASSIGN && 295743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen property != NULL && 295843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen property->obj()->AsVariableProxy() != NULL && 295943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen property->obj()->AsVariableProxy()->is_this()) { 2960c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org current_function_state_->AddProperty(); 296143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 296243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 296321b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org // If we assign a function literal to a property we pretenure the 296421b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org // literal so it can be added as a constant function property. 296521b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org if (property != NULL && right->AsFunctionLiteral() != NULL) { 2966c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org right->AsFunctionLiteral()->set_pretenure(); 296721b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org } 296821b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org 296965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) { 297065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Check if the right hand side is a call to avoid inferring a 297165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // name if we're dealing with "a = function(){...}();"-like 297265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // expression. 297365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if ((op == Token::INIT_VAR 297465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org || op == Token::INIT_CONST 297565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org || op == Token::ASSIGN) 297604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org && (right->AsCall() == NULL && right->AsCallNew() == NULL)) { 297765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->Infer(); 2978c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2979c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fni_->RemoveLastFunction(); 298065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 298165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->Leave(); 298265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 298365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 2984b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewAssignment(op, expression, right, pos); 298543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 298643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 298743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2988f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgExpression* Parser::ParseYieldExpression(bool* ok) { 2989f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // YieldExpression :: 2990f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // 'yield' '*'? AssignmentExpression 2991a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 2992f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Expect(Token::YIELD, CHECK_OK); 299377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Yield::Kind kind = 299477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; 2995e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Expression* generator_object = factory()->NewVariableProxy( 2996e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org current_function_state_->generator_object_variable()); 2997f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Expression* expression = ParseAssignmentExpression(false, CHECK_OK); 2998a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); 29994e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (kind == Yield::DELEGATING) { 30004e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org yield->set_index(current_function_state_->NextHandlerIndex()); 30014e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 30024e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org return yield; 3003f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org} 3004f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 3005f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 300643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence = 3 300743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { 300843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ConditionalExpression :: 300943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LogicalOrExpression 301043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 301143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3012a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 301343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We start using the binary expression parser for prec >= 4 only! 301443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); 301543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::CONDITIONAL) return expression; 301643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::CONDITIONAL); 301743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // In parsing the first assignment expression in conditional 301843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // expressions we always accept the 'in' keyword; see ECMA-262, 301943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // section 11.12, page 58. 302043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* left = ParseAssignmentExpression(true, CHECK_OK); 302143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COLON, CHECK_OK); 302243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 3023a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewConditional(expression, left, right, pos); 302443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 302543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 302643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3027b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgint ParserBase::Precedence(Token::Value tok, bool accept_IN) { 302843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tok == Token::IN && !accept_IN) 302943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; // 0 precedence will terminate binary expression parsing 303043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 303143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return Token::Precedence(tok); 303243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 303343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 303443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 303543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence >= 4 303643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { 303743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(prec >= 4); 303843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* x = ParseUnaryExpression(CHECK_OK); 303943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 304043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // prec1 >= 4 304143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (Precedence(peek(), accept_IN) == prec1) { 304243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value op = Next(); 3043a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 304443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); 304543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 304643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute some expressions involving only number literals. 30471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() && 30481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { 30491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org double x_val = x->AsLiteral()->value()->Number(); 30501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org double y_val = y->AsLiteral()->value()->Number(); 305143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 305243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (op) { 305343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::ADD: 3054a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewNumberLiteral(x_val + y_val, pos); 305543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 305643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SUB: 3057a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewNumberLiteral(x_val - y_val, pos); 305843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 305943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::MUL: 3060a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewNumberLiteral(x_val * y_val, pos); 306143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 306243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::DIV: 3063a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewNumberLiteral(x_val / y_val, pos); 306443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 3065b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org case Token::BIT_OR: { 3066b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); 3067a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewNumberLiteral(value, pos); 306843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 3069b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org } 3070b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org case Token::BIT_AND: { 3071b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); 3072a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewNumberLiteral(value, pos); 307343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 3074b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org } 3075b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org case Token::BIT_XOR: { 3076b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); 3077a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewNumberLiteral(value, pos); 307843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 3079b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org } 308043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SHL: { 308143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); 3082a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewNumberLiteral(value, pos); 308343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 308443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 308543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SHR: { 308643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t shift = DoubleToInt32(y_val) & 0x1f; 308743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t value = DoubleToUint32(x_val) >> shift; 3088a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewNumberLiteral(value, pos); 308943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 309043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 309143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SAR: { 309243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t shift = DoubleToInt32(y_val) & 0x1f; 309343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); 3094a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewNumberLiteral(value, pos); 309543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 309643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 309743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 309843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 309943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 310043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 310143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 310243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // For now we distinguish between comparisons and other binary 310343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // operations. (We could combine the two and get rid of this 310465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // code and AST node eventually.) 310543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (Token::IsCompareOp(op)) { 310643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We have a comparison. 310743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value cmp = op; 310843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (op) { 310943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::NE: cmp = Token::EQ; break; 311043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; 311143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: break; 311243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3113a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewCompareOperation(cmp, x, y, pos); 311443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (cmp != op) { 311543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The comparison was negated - add a NOT. 3116a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewUnaryOperation(Token::NOT, x, pos); 311743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 311843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 311943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 312043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We have a "normal" binary operation. 3121a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org x = factory()->NewBinaryOperation(op, x, y, pos); 312243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 312343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 312443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 312543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return x; 312643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 312743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 312843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 312943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseUnaryExpression(bool* ok) { 313043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // UnaryExpression :: 313143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // PostfixExpression 313243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'delete' UnaryExpression 313343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'void' UnaryExpression 313443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'typeof' UnaryExpression 313543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '++' UnaryExpression 313643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '--' UnaryExpression 313743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '+' UnaryExpression 313843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '-' UnaryExpression 313943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '~' UnaryExpression 314043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '!' UnaryExpression 314143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 314243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value op = peek(); 314343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (Token::IsUnaryOp(op)) { 314443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen op = Next(); 3145a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 3146c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Expression* expression = ParseUnaryExpression(CHECK_OK); 314743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31487b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (expression != NULL && (expression->AsLiteral() != NULL)) { 31491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Object> literal = expression->AsLiteral()->value(); 31507b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (op == Token::NOT) { 31517b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // Convert the literal to a boolean condition and negate it. 31529faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org bool condition = literal->BooleanValue(); 3153fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Handle<Object> result = isolate()->factory()->ToBoolean(!condition); 3154a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewLiteral(result, pos); 31557b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } else if (literal->IsNumber()) { 31567b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // Compute some expressions involving only number literals. 31577b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org double value = literal->Number(); 31587b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org switch (op) { 31597b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org case Token::ADD: 31607b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org return expression; 31617b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org case Token::SUB: 3162a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewNumberLiteral(-value, pos); 31637b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org case Token::BIT_NOT: 3164a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); 31657b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org default: 31667b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org break; 31677b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 316843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 316943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 317043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 317149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // "delete identifier" is a syntax error in strict mode. 31721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (op == Token::DELETE && !top_scope_->is_classic_mode()) { 317349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org VariableProxy* operand = expression->AsVariableProxy(); 317449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (operand != NULL && !operand->is_this()) { 317549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org ReportMessage("strict_delete", Vector<const char*>::empty()); 317649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org *ok = false; 317749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org return NULL; 317849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 317949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 318049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 3181b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org // Desugar '+foo' into 'foo*1', this enables the collection of type feedback 3182b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org // without any special stub and the multiplication is removed later in 3183b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org // Crankshaft's canonicalization pass. 3184b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (op == Token::ADD) { 3185b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org return factory()->NewBinaryOperation(Token::MUL, 3186b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org expression, 3187a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewNumberLiteral(1, pos), 3188a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos); 3189b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 3190594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The same idea for '-foo' => 'foo*(-1)'. 3191594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (op == Token::SUB) { 3192594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return factory()->NewBinaryOperation(Token::MUL, 3193594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org expression, 3194a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewNumberLiteral(-1, pos), 3195a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos); 3196594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 3197594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // ...and one more time for '~foo' => 'foo^(~0)'. 3198594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (op == Token::BIT_NOT) { 3199594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return factory()->NewBinaryOperation(Token::BIT_XOR, 3200594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org expression, 3201a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewNumberLiteral(~0, pos), 3202a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos); 3203594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 3204b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 3205a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewUnaryOperation(op, expression, pos); 320643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 320743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (Token::IsCountOp(op)) { 320843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen op = Next(); 3209c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Expression* expression = ParseUnaryExpression(CHECK_OK); 3210c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Signal a reference error if the expression is an invalid 3211c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // left-hand side expression. We could report this as a syntax 3212c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // error here but for compatibility with JSC we choose to report the 3213c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // error at runtime. 3214c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org if (expression == NULL || !expression->IsValidLeftHandSide()) { 3215dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message = 32164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->invalid_lhs_in_prefix_op_string(); 3217dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org expression = NewThrowReferenceError(message); 321843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3219378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 32201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode()) { 3221378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Prefix expression operand in strict mode may not be eval or arguments. 3222378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); 3223378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 322464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MarkAsLValue(expression); 3225378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3226b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewCountOperation(op, 3227b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org true /* prefix */, 3228b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org expression, 3229a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org position()); 323043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 323143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 323243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return ParsePostfixExpression(ok); 323343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 323443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 323543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 323643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 323743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParsePostfixExpression(bool* ok) { 323843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // PostfixExpression :: 323943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LeftHandSideExpression ('++' | '--')? 324043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3241c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Expression* expression = ParseLeftHandSideExpression(CHECK_OK); 3242df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org if (!scanner().HasAnyLineTerminatorBeforeNext() && 32435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Token::IsCountOp(peek())) { 3244c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Signal a reference error if the expression is an invalid 3245c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // left-hand side expression. We could report this as a syntax 3246c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // error here but for compatibility with JSC we choose to report the 3247c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // error at runtime. 3248c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org if (expression == NULL || !expression->IsValidLeftHandSide()) { 3249dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message = 32504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->invalid_lhs_in_postfix_op_string(); 3251dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org expression = NewThrowReferenceError(message); 325243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3253378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 32541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode()) { 3255378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Postfix expression operand in strict mode may not be eval or arguments. 3256378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); 3257378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 325864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MarkAsLValue(expression); 3259378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 326043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value next = Next(); 3261c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org expression = 3262b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewCountOperation(next, 3263b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org false /* postfix */, 3264b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org expression, 3265a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org position()); 326643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3267c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org return expression; 326843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 326943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 327043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 327143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseLeftHandSideExpression(bool* ok) { 327243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LeftHandSideExpression :: 327343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // (NewExpression | MemberExpression) ... 327443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 327543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* result; 327643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::NEW) { 327743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseNewExpression(CHECK_OK); 327843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 327943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseMemberExpression(CHECK_OK); 328043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 328143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 328243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (true) { 328343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (peek()) { 328443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LBRACK: { 328543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::LBRACK); 3286a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 328743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* index = ParseExpression(true, CHECK_OK); 3288b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewProperty(result, index, pos); 328943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACK, CHECK_OK); 329043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 329143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 329243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 329343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LPAREN: { 3294f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com int pos; 3295f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com if (scanner().current_token() == Token::IDENTIFIER) { 3296f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // For call of an identifier we want to report position of 3297f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // the identifier as position of the call in the stack trace. 3298a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos = position(); 3299f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } else { 3300f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // For other kinds of calls we record position of the parenthesis as 3301f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // position of the call. Note that this is extremely important for 3302f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // expressions of the form function(){...}() for which call position 3303f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // should not point to the closing brace otherwise it will intersect 3304f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // with positions recorded for function literal and confuse debugger. 3305a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos = peek_position(); 3306de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org // Also the trailing parenthesis are a hint that the function will 3307de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org // be called immediately. If we happen to have parsed a preceding 3308de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org // function literal eagerly, we can also compile it eagerly. 3309de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { 3310de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org result->AsFunctionLiteral()->set_parenthesized(); 3311de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org } 3312f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } 331343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 331443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 331543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Keep track of eval() calls since they disable all local variable 3316a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // optimizations. 3317a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // The calls that need special treatment are the 3318c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // direct eval calls. These calls are all of the form eval(...), with 3319c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // no explicit receiver. 3320c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // These calls are marked as potentially direct eval calls. Whether 3321c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // they are actually direct calls to eval is determined at run time. 3322fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org VariableProxy* callee = result->AsVariableProxy(); 3323ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (callee != NULL && 33244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org callee->IsVariable(isolate()->factory()->eval_string())) { 3325c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org top_scope_->DeclarationScope()->RecordEvalCall(); 332643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3327b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewCall(result, args, pos); 332879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org if (fni_ != NULL) fni_->RemoveLastFunction(); 332943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 333043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 333143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 333243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::PERIOD: { 333343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::PERIOD); 3334a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 3335d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org Handle<String> name = ParseIdentifierName(CHECK_OK); 3336a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewProperty( 3337a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result, factory()->NewLiteral(name, pos), pos); 333865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushLiteralName(name); 333943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 334043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 334143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 334243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 334343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 334443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 334543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 334643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 334743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 334843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3349b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgExpression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { 335043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // NewExpression :: 335143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ('new')+ MemberExpression 335243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 335343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The grammar for new expressions is pretty warped. The keyword 335443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'new' can either be a part of the new expression (where it isn't 335543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // followed by an argument list) or a part of the member expression, 335643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // where it must be followed by an argument list. To accommodate 335743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // this, we parse the 'new' keywords greedily and keep track of how 335843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // many we have parsed. This information is then passed on to the 335943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // member expression parser, which is only allowed to match argument 336043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // lists as long as it has 'new' prefixes left 3361b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Expect(Token::NEW, CHECK_OK); 3362a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org PositionStack::Element pos(stack, position()); 3363b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 3364b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Expression* result; 3365b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org if (peek() == Token::NEW) { 3366b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org result = ParseNewPrefix(stack, CHECK_OK); 3367b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org } else { 3368b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); 336943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 337043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3371b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org if (!stack->is_empty()) { 3372b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org int last = stack->pop(); 3373b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewCallNew( 33747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org result, new(zone()) ZoneList<Expression*>(0, zone()), last); 337543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 337643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 337743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 337843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 337943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3380b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgExpression* Parser::ParseNewExpression(bool* ok) { 3381b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org PositionStack stack(ok); 3382b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org return ParseNewPrefix(&stack, ok); 3383b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 3384b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 3385b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 338643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseMemberExpression(bool* ok) { 3387b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org return ParseMemberWithNewPrefixesExpression(NULL, ok); 338843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 338943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 339043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3391b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgExpression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, 3392b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org bool* ok) { 339343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // MemberExpression :: 339443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // (PrimaryExpression | FunctionLiteral) 339543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ('[' Expression ']' | '.' Identifier | Arguments)* 339643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 339743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse the initial primary or function expression. 339843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* result = NULL; 339943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::FUNCTION) { 340043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::FUNCTION, CHECK_OK); 3401a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int function_token_position = position(); 3402e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool is_generator = allow_generators() && Check(Token::MUL); 340343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> name; 340404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool is_strict_reserved_name = false; 340583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (peek_any_identifier()) { 340604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 340704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org CHECK_OK); 340883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 3409dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org FunctionLiteral::FunctionType function_type = name.is_null() 34107c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org ? FunctionLiteral::ANONYMOUS_EXPRESSION 34117c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org : FunctionLiteral::NAMED_EXPRESSION; 34127c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org result = ParseFunctionLiteral(name, 34137c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org is_strict_reserved_name, 3414f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org is_generator, 34157c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org function_token_position, 3416dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org function_type, 34177c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org CHECK_OK); 341843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 341943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParsePrimaryExpression(CHECK_OK); 342043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 342143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 342243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (true) { 342343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (peek()) { 342443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LBRACK: { 342543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::LBRACK); 3426a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 342743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* index = ParseExpression(true, CHECK_OK); 3428b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewProperty(result, index, pos); 342904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (fni_ != NULL) { 343004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (index->IsPropertyName()) { 343104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); 343204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } else { 343304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org fni_->PushLiteralName( 34344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->anonymous_function_string()); 343504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 343604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 343743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACK, CHECK_OK); 343843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 343943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 344043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::PERIOD: { 344143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::PERIOD); 3442a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 3443d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org Handle<String> name = ParseIdentifierName(CHECK_OK); 3444a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewProperty( 3445a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result, factory()->NewLiteral(name, pos), pos); 344665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushLiteralName(name); 344743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 344843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 344943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LPAREN: { 3450b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org if ((stack == NULL) || stack->is_empty()) return result; 345143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Consume one of the new prefixes (already parsed). 345243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 3453a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = stack->pop(); 3454a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewCallNew(result, args, pos); 345543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 345643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 345743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 345843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 345943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 346043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 346143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 346243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 346343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 346443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { 346543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 346643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // contexts this is used as a statement which invokes the debugger as i a 346743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // break point is present. 346843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // DebuggerStatement :: 346943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'debugger' ';' 347043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3471a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 347243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::DEBUGGER, CHECK_OK); 347343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 3474a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewDebuggerStatement(pos); 347543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 347643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 347743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 347843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Parser::ReportUnexpectedToken(Token::Value token) { 347943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We don't report stack overflows here, to avoid increasing the 348043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // stack depth even further. Instead we report it after parsing is 3481b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // over, in ParseProgram/ParseJson. 3482a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org if (token == Token::ILLEGAL && stack_overflow()) return; 348343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Four of the tokens are treated specially 348443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (token) { 3485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::EOS: 3486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return ReportMessage("unexpected_eos", Vector<const char*>::empty()); 3487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::NUMBER: 3488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return ReportMessage("unexpected_token_number", 3489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Vector<const char*>::empty()); 3490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::STRING: 3491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return ReportMessage("unexpected_token_string", 3492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Vector<const char*>::empty()); 3493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::IDENTIFIER: 3494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return ReportMessage("unexpected_token_identifier", 3495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Vector<const char*>::empty()); 349683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::FUTURE_RESERVED_WORD: 349704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org return ReportMessage("unexpected_reserved", 349804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org Vector<const char*>::empty()); 3499f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org case Token::YIELD: 350004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org case Token::FUTURE_STRICT_RESERVED_WORD: 35011b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return ReportMessage(top_scope_->is_classic_mode() ? 35021b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org "unexpected_token_identifier" : 35031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org "unexpected_strict_reserved", 350483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Vector<const char*>::empty()); 3505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: 3506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const char* name = Token::String(token); 3507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(name != NULL); 3508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); 350943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 351043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 351143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 351243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35134a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.comvoid Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { 351483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); 35154a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com const char* element[1] = { *name_string }; 35164a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com ReportMessage("invalid_preparser_data", 35174a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com Vector<const char*>(element, 1)); 35184a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com *ok = false; 35194a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com} 35204a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com 35214a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com 352243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParsePrimaryExpression(bool* ok) { 352343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // PrimaryExpression :: 352443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'this' 352543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'null' 352643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'true' 352743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'false' 352843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Identifier 352943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Number 353043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // String 353143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ArrayLiteral 353243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ObjectLiteral 353343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // RegExpLiteral 353443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '(' Expression ')' 353543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3536a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 353743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* result = NULL; 353843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (peek()) { 353943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::THIS: { 354043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::THIS); 3541b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewVariableProxy(top_scope_->receiver()); 354243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 354343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 354443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 354543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::NULL_LITERAL: 354643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::NULL_LITERAL); 3547a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewLiteral(isolate()->factory()->null_value(), pos); 354843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 354943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 355043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::TRUE_LITERAL: 355143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::TRUE_LITERAL); 3552a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewLiteral(isolate()->factory()->true_value(), pos); 355343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 355443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 355543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::FALSE_LITERAL: 355643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::FALSE_LITERAL); 3557a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewLiteral(isolate()->factory()->false_value(), pos); 355843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 355943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 356083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::IDENTIFIER: 3561f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org case Token::YIELD: 356204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org case Token::FUTURE_STRICT_RESERVED_WORD: { 356343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> name = ParseIdentifier(CHECK_OK); 356465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushVariableName(name); 3565bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // The name may refer to a module instance object, so its type is unknown. 3566bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 3567bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 3568bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Variable %s ", name->ToAsciiArray()); 3569bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 35707028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Interface* interface = Interface::NewUnknown(zone()); 3571a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = top_scope_->NewUnresolved(factory(), name, interface, pos); 357243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 357343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 357443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 357543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::NUMBER: { 357643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::NUMBER); 35779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org ASSERT(scanner().is_literal_ascii()); 3578a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org double value = StringToDouble(isolate()->unicode_cache(), 3579a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org scanner().literal_ascii_string(), 3580ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ALLOW_HEX | ALLOW_OCTAL | 3581ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); 3582a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewNumberLiteral(value, pos); 358343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 358443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 358543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 358643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::STRING: { 358743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::STRING); 3588bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org Handle<String> symbol = GetSymbol(); 3589a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org result = factory()->NewLiteral(symbol, pos); 359065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushLiteralName(symbol); 359143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 359243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 359343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 359443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::ASSIGN_DIV: 359543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseRegExpLiteral(true, CHECK_OK); 359643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 359743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 359843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::DIV: 359943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseRegExpLiteral(false, CHECK_OK); 360043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 360143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 360243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LBRACK: 360343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseArrayLiteral(CHECK_OK); 360443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 360543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 360643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LBRACE: 360743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseObjectLiteral(CHECK_OK); 360843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 360943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 361043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LPAREN: 361143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::LPAREN); 3612c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Heuristically try to detect immediately called functions before 3613c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // seeing the call parentheses. 3614c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org parenthesized_function_ = (peek() == Token::FUNCTION); 361543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseExpression(true, CHECK_OK); 361643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 361743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 361843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 361943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::MOD: 3620e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (allow_natives_syntax() || extension_ != NULL) { 362143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseV8Intrinsic(CHECK_OK); 362243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 362343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 362443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we're not allowing special syntax we fall-through to the 362543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // default case. 362643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 362743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: { 3628c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Token::Value tok = Next(); 362943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReportUnexpectedToken(tok); 363043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 363143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 363243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 363343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 363443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 363543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 363643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 363743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 363843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 363943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseArrayLiteral(bool* ok) { 364043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ArrayLiteral :: 364143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '[' Expression? (',' Expression?)* ']' 364243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3643a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 36447028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); 364543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACK, CHECK_OK); 364643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::RBRACK) { 364743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* elem; 364843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::COMMA) { 3649a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org elem = GetLiteralTheHole(peek_position()); 365043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 365143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen elem = ParseAssignmentExpression(true, CHECK_OK); 365243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 36537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org values->Add(elem, zone()); 365443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::RBRACK) { 365543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COMMA, CHECK_OK); 365643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 365743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 365843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACK, CHECK_OK); 36599a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 36609a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com // Update the scope information before the pre-parsing bailout. 3661c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org int literal_index = current_function_state_->NextMaterializedLiteralIndex(); 36629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 3663e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return factory()->NewArrayLiteral(values, literal_index, pos); 36649258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org} 36659258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 36669258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 3667bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgbool CompileTimeValue::IsCompileTimeValue(Expression* expression) { 3668a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (expression->AsLiteral() != NULL) return true; 3669bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org MaterializedLiteral* lit = expression->AsMaterializedLiteral(); 3670bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return lit != NULL && lit->is_simple(); 3671bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3672bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 36730b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 36743d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgHandle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, 36753d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Expression* expression) { 36763d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Factory* factory = isolate->factory(); 3677bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ASSERT(IsCompileTimeValue(expression)); 3678d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Handle<FixedArray> result = factory->NewFixedArray(2, TENURED); 3679bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ObjectLiteral* object_literal = expression->AsObjectLiteral(); 3680bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org if (object_literal != NULL) { 3681bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ASSERT(object_literal->is_simple()); 3682f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org if (object_literal->fast_elements()) { 3683dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS)); 3684f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } else { 3685dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS)); 3686f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } 3687bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org result->set(kElementsSlot, *object_literal->constant_properties()); 3688bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } else { 3689bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ArrayLiteral* array_literal = expression->AsArrayLiteral(); 3690bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ASSERT(array_literal != NULL && array_literal->is_simple()); 3691dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL)); 36920c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org result->set(kElementsSlot, *array_literal->constant_elements()); 3693bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 3694bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return result; 3695bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3696bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3697bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3698dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgCompileTimeValue::LiteralType CompileTimeValue::GetLiteralType( 3699dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<FixedArray> value) { 3700dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); 3701dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org return static_cast<LiteralType>(literal_type->value()); 3702bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3703bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3704bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3705bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgHandle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { 3706bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); 3707bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3708bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3709bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 371043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseObjectLiteral(bool* ok) { 371143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ObjectLiteral :: 371243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '{' ( 3713d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org // ((IdentifierName | String | Number) ':' AssignmentExpression) 3714d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 371543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // )*[','] '}' 371643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3717a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 3718fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org ZoneList<ObjectLiteral::Property*>* properties = 37197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); 37209258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org int number_of_boilerplate_properties = 0; 3721ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org bool has_function = false; 372243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3723b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org ObjectLiteralChecker checker(this, top_scope_->language_mode()); 3724378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 372543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 3726378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 372743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::RBRACE) { 372865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Enter(); 372965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 373043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Literal* key = NULL; 3731d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org Token::Value next = peek(); 3732a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int next_pos = peek_position(); 3733378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3734d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org switch (next) { 373583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::FUTURE_RESERVED_WORD: 373604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org case Token::FUTURE_STRICT_RESERVED_WORD: 373743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::IDENTIFIER: { 373843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool is_getter = false; 373943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool is_setter = false; 374043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> id = 374104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 374265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushLiteralName(id); 374365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 3744c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if ((is_getter || is_setter) && peek() != Token::COLON) { 3745dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org // Special handling of getter and setter syntax: 3746dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 3747dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org // We have already read the "get" or "set" keyword. 3748dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org Token::Value next = Next(); 3749dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org bool is_keyword = Token::IsKeyword(next); 3750dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org if (next != i::Token::IDENTIFIER && 3751dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org next != i::Token::FUTURE_RESERVED_WORD && 3752dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org next != i::Token::FUTURE_STRICT_RESERVED_WORD && 3753dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org next != i::Token::NUMBER && 3754dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org next != i::Token::STRING && 3755dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org !is_keyword) { 3756dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org // Unexpected token. 3757dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org ReportUnexpectedToken(next); 3758dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org *ok = false; 3759dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org return NULL; 3760dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org } 3761dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org // Validate the property. 3762dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; 3763dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org checker.CheckProperty(next, type, CHECK_OK); 3764dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org Handle<String> name = is_keyword 3765dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org ? isolate_->factory()->InternalizeUtf8String(Token::String(next)) 3766dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org : GetSymbol(); 3767dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org FunctionLiteral* value = 3768dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org ParseFunctionLiteral(name, 3769dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org false, // reserved words are allowed here 3770dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org false, // not a generator 3771dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org RelocInfo::kNoPosition, 3772dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org FunctionLiteral::ANONYMOUS_EXPRESSION, 3773dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org CHECK_OK); 3774dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org // Allow any number of parameters for compatibilty with JSC. 3775dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org // Specification only allows zero parameters for get and one for set. 3776dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org ObjectLiteral::Property* property = 3777a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewObjectLiteralProperty(is_getter, value, next_pos); 3778e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (ObjectLiteral::IsBoilerplateProperty(property)) { 3779dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org number_of_boilerplate_properties++; 3780dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org } 3781dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org properties->Add(property, zone()); 3782dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 3783dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org 3784dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org if (fni_ != NULL) { 3785dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org fni_->Infer(); 3786dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org fni_->Leave(); 3787dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org } 3788dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org continue; // restart the while 378943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3790c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // Failed to parse as get/set property, so it's just a property 3791c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // called "get" or "set". 3792a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org key = factory()->NewLiteral(id, next_pos); 379343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 379443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 379543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::STRING: { 3796c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Consume(Token::STRING); 3797bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org Handle<String> string = GetSymbol(); 379865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushLiteralName(string); 379943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t index; 380026c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org if (!string.is_null() && string->AsArrayIndex(&index)) { 3801a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org key = factory()->NewNumberLiteral(index, next_pos); 3802c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org break; 380343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3804a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org key = factory()->NewLiteral(string, next_pos); 380543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 380643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 380743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::NUMBER: { 380843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::NUMBER); 38099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org ASSERT(scanner().is_literal_ascii()); 3810a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org double value = StringToDouble(isolate()->unicode_cache(), 3811a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org scanner().literal_ascii_string(), 3812ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ALLOW_HEX | ALLOW_OCTAL | 3813ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); 3814a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org key = factory()->NewNumberLiteral(value, next_pos); 381543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 381643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 381743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 3818c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if (Token::IsKeyword(next)) { 3819c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Consume(next); 3820bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org Handle<String> string = GetSymbol(); 3821a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org key = factory()->NewLiteral(string, next_pos); 3822c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } else { 3823c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // Unexpected token. 3824c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Token::Value next = Next(); 3825c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org ReportUnexpectedToken(next); 3826c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org *ok = false; 3827c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org return NULL; 3828c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 382943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 383043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3831dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org // Validate the property 3832dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org checker.CheckProperty(next, kValueProperty, CHECK_OK); 3833dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org 383443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COLON, CHECK_OK); 383543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* value = ParseAssignmentExpression(true, CHECK_OK); 383643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 383743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ObjectLiteral::Property* property = 3838812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org new(zone()) ObjectLiteral::Property(key, value, isolate()); 38399258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 3840ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org // Mark top-level object literals that contain function literals and 3841ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org // pretenure the literal so it can be added as a constant function 3842ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org // property. 3843ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org if (top_scope_->DeclarationScope()->is_global_scope() && 3844ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org value->AsFunctionLiteral() != NULL) { 3845ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org has_function = true; 3846c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org value->AsFunctionLiteral()->set_pretenure(); 3847ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 3848ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 38499258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 3850e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (ObjectLiteral::IsBoilerplateProperty(property)) { 3851e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org number_of_boilerplate_properties++; 3852e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 38537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org properties->Add(property, zone()); 385443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 385543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1240767): Consider allowing trailing comma. 385643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 385765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 385865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) { 385965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->Infer(); 386065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->Leave(); 386165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 386243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 386343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACE, CHECK_OK); 3864378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 386543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Computation of literal_index must happen before pre parse bailout. 3866c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org int literal_index = current_function_state_->NextMaterializedLiteralIndex(); 386743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3868e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return factory()->NewObjectLiteral(properties, 3869b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org literal_index, 3870e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org number_of_boilerplate_properties, 3871a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org has_function, 3872a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos); 387343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 387443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 387543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 387643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { 3877a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 38785f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org if (!scanner().ScanRegExpPattern(seen_equal)) { 387943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 388043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReportMessage("unterminated_regexp", Vector<const char*>::empty()); 388143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 388243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 388343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 388443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3885c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org int literal_index = current_function_state_->NextMaterializedLiteralIndex(); 388643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org Handle<String> js_pattern = NextLiteralString(TENURED); 38885f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org scanner().ScanRegExpFlags(); 38899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org Handle<String> js_flags = NextLiteralString(TENURED); 389043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 389143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3892a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); 389343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 389443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 389543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 389643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenZoneList<Expression*>* Parser::ParseArguments(bool* ok) { 389743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Arguments :: 389843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '(' (AssignmentExpression)*[','] ')' 389943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 39007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); 390143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 390243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool done = (peek() == Token::RPAREN); 390343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!done) { 390443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* argument = ParseAssignmentExpression(true, CHECK_OK); 39057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org result->Add(argument, zone()); 3906876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org if (result->length() > Code::kMaxArguments) { 3907e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org ReportMessageAt(scanner().location(), "too_many_arguments", 3908e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Vector<const char*>::empty()); 3909e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org *ok = false; 3910e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org return NULL; 3911e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 391243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen done = (peek() == Token::RPAREN); 391343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!done) Expect(Token::COMMA, CHECK_OK); 391443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 391543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 3916fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org return result; 391743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 391843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 391943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 39201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgclass SingletonLogger : public ParserRecorder { 39211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org public: 39221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SingletonLogger() : has_error_(false), start_(-1), end_(-1) { } 3923b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org virtual ~SingletonLogger() { } 39241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org void Reset() { has_error_ = false; } 39261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual void LogFunction(int start, 39281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int end, 39291b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int literals, 39301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int properties, 39311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org LanguageMode mode) { 39321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(!has_error_); 39331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org start_ = start; 39341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org end_ = end; 39351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org literals_ = literals; 39361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org properties_ = properties; 39371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org mode_ = mode; 39381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org }; 39391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Logs a symbol creation of a literal or identifier. 39411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual void LogAsciiSymbol(int start, Vector<const char> literal) { } 3942154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { } 39431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Logs an error message and marks the log as containing an error. 39451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Further logging will be ignored, and ExtractData will return a vector 39461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // representing the error only. 39471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual void LogMessage(int start, 39481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int end, 39491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* message, 39501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* argument_opt) { 3951657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org if (has_error_) return; 39521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org has_error_ = true; 39531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org start_ = start; 39541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org end_ = end; 39551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org message_ = message; 39561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org argument_opt_ = argument_opt; 39571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 39581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual int function_position() { return 0; } 39601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual int symbol_position() { return 0; } 39621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual int symbol_ids() { return -1; } 39641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual Vector<unsigned> ExtractData() { 39661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org UNREACHABLE(); 39671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return Vector<unsigned>(); 39681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 39691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual void PauseRecording() { } 39711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual void ResumeRecording() { } 39731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org bool has_error() { return has_error_; } 39751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int start() { return start_; } 39771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int end() { return end_; } 39781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int literals() { 39791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(!has_error_); 39801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return literals_; 39811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 39821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int properties() { 39831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(!has_error_); 39841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return properties_; 39851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 39861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org LanguageMode language_mode() { 39871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(!has_error_); 39881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return mode_; 39891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 39901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* message() { 39911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(has_error_); 39921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return message_; 39931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 39941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* argument_opt() { 39951b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(has_error_); 39961b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return argument_opt_; 39971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 39981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 39991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org private: 40001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org bool has_error_; 40011b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int start_; 40021b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int end_; 40031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // For function entries. 40041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int literals_; 40051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int properties_; 40061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org LanguageMode mode_; 40071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // For error messages. 40081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* message_; 40091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* argument_opt_; 40101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org}; 40111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 40121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 4013dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgFunctionLiteral* Parser::ParseFunctionLiteral( 4014dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> function_name, 4015dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org bool name_is_strict_reserved, 4016dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org bool is_generator, 4017a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int function_token_pos, 4018dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org FunctionLiteral::FunctionType function_type, 4019dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org bool* ok) { 402043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Function :: 402143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '(' FormalParameterList? ')' '{' FunctionBody '}' 402243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4023a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = function_token_pos == RelocInfo::kNoPosition 4024a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ? peek_position() : function_token_pos; 4025a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org 40267c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // Anonymous functions were passed either the empty symbol or a null 40277c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // handle as the function name. Remember if we were passed a non-empty 40287c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // handle to decide whether to invoke function name inference. 40297c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org bool should_infer_name = function_name.is_null(); 40307c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 40317c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // We want a non-null handle as the function name. 40327c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org if (should_infer_name) { 40334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org function_name = isolate()->factory()->empty_string(); 403443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 403543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 403643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int num_parameters = 0; 4037b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // Function declarations are function scoped in normal mode, so they are 4038b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // hoisted. In harmony block scoping mode they are block scoped, so they 4039b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // are not hoisted. 40401e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // 40411e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // One tricky case are function declarations in a local sloppy-mode eval: 40421e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // their declaration is hoisted, but they still see the local scope. E.g., 40431e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // 40441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // function() { 40451e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // var x = 0 40461e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // try { throw 1 } catch (x) { eval("function g() { return x }") } 40471e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // return g() 40481e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // } 40491e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // 40501e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // needs to return 1. To distinguish such cases, we need to detect 40511e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // (1) whether a function stems from a sloppy eval, and 40521e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // (2) whether it actually hoists across the eval. 40531e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Unfortunately, we do not represent sloppy eval scopes, so we do not have 40541e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // either information available directly, especially not when lazily compiling 40551e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // a function like 'g'. We hence rely on the following invariants: 40561e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // - (1) is the case iff the innermost scope of the deserialized scope chain 40571e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // under which we compile is _not_ a declaration scope. This holds because 40581e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // in all normal cases, function declarations are fully hoisted to a 40591e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // declaration scope and compiled relative to that. 40601e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // - (2) is the case iff the current declaration scope is still the original 40611e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // one relative to the deserialized scope chain. Otherwise we must be 40621e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // compiling a function in an inner declaration scope in the eval, e.g. a 40631e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // nested function, and hoisting works normally relative to that. 40641e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Scope* declaration_scope = top_scope_->DeclarationScope(); 40651e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Scope* original_declaration_scope = original_scope_->DeclarationScope(); 4066dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Scope* scope = 40671e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org function_type == FunctionLiteral::DECLARATION && !is_extended_mode() && 40681e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org (original_scope_ == original_declaration_scope || 40691e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org declaration_scope != original_declaration_scope) 40701e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org ? NewScope(declaration_scope, FUNCTION_SCOPE) 40711e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org : NewScope(top_scope_, FUNCTION_SCOPE); 407204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ZoneList<Statement*>* body = NULL; 40731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int materialized_literal_count = -1; 40741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int expected_property_count = -1; 407504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int handler_count = 0; 407656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org FunctionLiteral::ParameterFlag duplicate_parameters = 407756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org FunctionLiteral::kNoDuplicateParameters; 4078471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ 4079471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ? FunctionLiteral::kIsParenthesized 4080471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org : FunctionLiteral::kNotParenthesized; 4081f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org FunctionLiteral::IsGeneratorFlag generator = is_generator 4082f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ? FunctionLiteral::kIsGenerator 4083f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org : FunctionLiteral::kNotGenerator; 4084b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org AstProperties ast_properties; 40852c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org BailoutReason dont_optimize_reason = kNoReason; 408643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse function body. 4087e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org { FunctionState function_state(this, scope, isolate()); 40887c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org top_scope_->SetScopeName(function_name); 408943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4090e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (is_generator) { 4091e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // For generators, allocating variables in contexts is currently a win 4092e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // because it minimizes the work needed to suspend and resume an 4093e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // activation. 4094e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org top_scope_->ForceContextAllocation(); 4095e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4096e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Calling a generator returns a generator object. That object is stored 4097e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // in a temporary variable, a definition that is used by "yield" 4098e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // expressions. Presence of a variable for the generator object in the 4099e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // FunctionState indicates that this function is a generator. 4100e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Variable* temp = top_scope_->DeclarationScope()->NewTemporary( 4101e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org isolate()->factory()->dot_generator_object_string()); 4102e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org function_state.set_generator_object_variable(temp); 4103e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 4104e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 410543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // FormalParameterList :: 410643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '(' (Identifier)*[','] ')' 410743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 4108394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->set_start_position(scanner().location().beg_pos); 41091c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Scanner::Location name_loc = Scanner::Location::invalid(); 41101c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Scanner::Location dupe_loc = Scanner::Location::invalid(); 41111c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Scanner::Location reserved_loc = Scanner::Location::invalid(); 41120a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 411343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool done = (peek() == Token::RPAREN); 411443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!done) { 411504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool is_strict_reserved = false; 411683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Handle<String> param_name = 41170cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 4118378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 4119378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Store locations for possible future error reports. 4120378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { 4121378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org name_loc = scanner().location(); 4122378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 4123378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { 412456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; 4125378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org dupe_loc = scanner().location(); 4126378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 412704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (!reserved_loc.IsValid() && is_strict_reserved) { 412883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org reserved_loc = scanner().location(); 412983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 4130378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 413156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org top_scope_->DeclareParameter(param_name, VAR); 4132fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org num_parameters++; 4133876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org if (num_parameters > Code::kMaxArguments) { 4134d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ReportMessageAt(scanner().location(), "too_many_parameters", 4135d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com Vector<const char*>::empty()); 4136d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com *ok = false; 4137d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com return NULL; 4138d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 413943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen done = (peek() == Token::RPAREN); 414043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!done) Expect(Token::COMMA, CHECK_OK); 414143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 414243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 414343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 414443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 414543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 414643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we have a named function expression, we add a local variable 414743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration to the body of the function with the name of the 414843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function and let it refer to the function itself (closure). 414943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // NOTE: We create a proxy and resolve it here so that in the 415043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // future we can change the AST to only refer to VariableProxies 415143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // instead of Variables and Proxis as is the case now. 415204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Variable* fvar = NULL; 415304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Token::Value fvar_init_op = Token::INIT_CONST; 4154dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org if (function_type == FunctionLiteral::NAMED_EXPRESSION) { 4155ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; 4156ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; 4157ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com fvar = new(zone()) Variable(top_scope_, 4158ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com function_name, fvar_mode, true /* is valid LHS */, 415928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); 4160ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableProxy* proxy = factory()->NewVariableProxy(fvar); 4161a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( 4162a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org proxy, fvar_mode, top_scope_, RelocInfo::kNoPosition); 4163ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com top_scope_->DeclareFunctionVar(fvar_declaration); 416443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 416543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 41661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Determine whether the function will be lazily compiled. 41671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // The heuristics are: 41681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // - It must not have been prohibited by the caller to Parse (some callers 41691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // need a full AST). 41709c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org // - The outer scope must allow lazy compilation of inner functions. 41711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // - The function mustn't be a function expression with an open parenthesis 41721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // before; we consider that a hint that the function will be called 41731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // immediately, and it would be a waste of time to make it lazily 41741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // compiled. 41751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // These are all things we can know at this point, without looking at the 41761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // function itself. 4177c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bool is_lazily_compiled = (mode() == PARSE_LAZILY && 41789c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org top_scope_->AllowsLazyCompilation() && 41791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org !parenthesized_function_); 4180c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org parenthesized_function_ = false; // The bit was set for this function only. 418143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4182d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (is_lazily_compiled) { 4183a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int function_block_pos = position(); 41841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org FunctionEntry entry; 4185e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (pre_parse_data_ != NULL) { 4186e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If we have pre_parse_data_, we use it to skip parsing the function 4187e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // body. The preparser data contains the information we need to 4188e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // construct the lazy function. 4189e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org entry = pre_parse_data()->GetFunctionEntry(function_block_pos); 41901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (entry.is_valid()) { 41911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (entry.end_pos() <= function_block_pos) { 41921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // End position greater than end of stream is safe, and hard 41931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // to check. 41941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ReportInvalidPreparseData(function_name, CHECK_OK); 41951b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 41961b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org scanner().SeekForward(entry.end_pos() - 1); 41971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 41981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org scope->set_end_position(entry.end_pos()); 41991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Expect(Token::RBRACE, CHECK_OK); 42001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org isolate()->counters()->total_preparse_skipped()->Increment( 42011b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org scope->end_position() - function_block_pos); 42021b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org materialized_literal_count = entry.literal_count(); 42031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org expected_property_count = entry.property_count(); 42041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org top_scope_->SetLanguageMode(entry.language_mode()); 42051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } else { 42061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org is_lazily_compiled = false; 42071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 4208d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } else { 42091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // With no preparser data, we partially parse the function, without 42101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // building an AST. This gathers the data needed to build a lazy 42111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // function. 42121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SingletonLogger logger; 4213a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); 4214a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org if (result == PreParser::kPreParseStackOverflow) { 42151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Propagate stack overflow. 4216a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org set_stack_overflow(); 42171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org *ok = false; 42181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return NULL; 4219d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 42201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (logger.has_error()) { 42211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* arg = logger.argument_opt(); 42221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Vector<const char*> args; 42231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (arg != NULL) { 42241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org args = Vector<const char*>(&arg, 1); 42251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 42261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ReportMessageAt(Scanner::Location(logger.start(), logger.end()), 42271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org logger.message(), args); 42281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org *ok = false; 42291b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return NULL; 42301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 42311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org scope->set_end_position(logger.end()); 42321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Expect(Token::RBRACE, CHECK_OK); 4233d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org isolate()->counters()->total_preparse_skipped()->Increment( 4234394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->end_position() - function_block_pos); 42351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org materialized_literal_count = logger.literals(); 42361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org expected_property_count = logger.properties(); 42371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org top_scope_->SetLanguageMode(logger.language_mode()); 42384a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com } 4239d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 4240d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 4241d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (!is_lazily_compiled) { 4242471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 42437028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org body = new(zone()) ZoneList<Statement*>(8, zone()); 424404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org if (fvar != NULL) { 424528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org VariableProxy* fproxy = top_scope_->NewUnresolved( 424628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org factory(), function_name, Interface::NewConst()); 424704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org fproxy->BindTo(fvar); 4248b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org body->Add(factory()->NewExpressionStatement( 4249b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewAssignment(fvar_init_op, 4250b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org fproxy, 4251a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewThisFunction(pos), 4252a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org RelocInfo::kNoPosition), 4253a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org RelocInfo::kNoPosition), zone()); 425404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org } 4255e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4256e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // For generators, allocate and yield an iterator on function entry. 4257e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (is_generator) { 4258e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ZoneList<Expression*>* arguments = 4259e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org new(zone()) ZoneList<Expression*>(0, zone()); 4260e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CallRuntime* allocation = factory()->NewCallRuntime( 4261e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org isolate()->factory()->empty_string(), 4262e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), 4263a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org arguments, pos); 4264e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org VariableProxy* init_proxy = factory()->NewVariableProxy( 4265e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org current_function_state_->generator_object_variable()); 4266e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Assignment* assignment = factory()->NewAssignment( 4267e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); 4268e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org VariableProxy* get_proxy = factory()->NewVariableProxy( 4269e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org current_function_state_->generator_object_variable()); 4270e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Yield* yield = factory()->NewYield( 427177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); 4272a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org body->Add(factory()->NewExpressionStatement( 4273a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org yield, RelocInfo::kNoPosition), zone()); 4274e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 4275e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 427633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); 4277fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org 427877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (is_generator) { 427977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org VariableProxy* get_proxy = factory()->NewVariableProxy( 428077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org current_function_state_->generator_object_variable()); 428177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Expression *undefined = factory()->NewLiteral( 4282a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); 428377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Yield* yield = factory()->NewYield( 428477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); 4285a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org body->Add(factory()->NewExpressionStatement( 4286a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org yield, RelocInfo::kNoPosition), zone()); 428777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 428877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 4289c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org materialized_literal_count = function_state.materialized_literal_count(); 4290c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org expected_property_count = function_state.expected_property_count(); 429104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org handler_count = function_state.handler_count(); 429243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4293d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Expect(Token::RBRACE, CHECK_OK); 4294394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->set_end_position(scanner().location().end_pos); 429543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 429643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 42970a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Validate strict mode. 42981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode()) { 42997c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org if (IsEvalOrArguments(function_name)) { 4300394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int start_pos = scope->start_position(); 4301a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int position = function_token_pos != RelocInfo::kNoPosition 4302a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); 430383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Scanner::Location location = Scanner::Location(position, start_pos); 430483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ReportMessageAt(location, 43050a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org "strict_function_name", Vector<const char*>::empty()); 43060a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org *ok = false; 43070a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return NULL; 43080a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 4309378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if (name_loc.IsValid()) { 4310378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ReportMessageAt(name_loc, "strict_param_name", 4311378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Vector<const char*>::empty()); 4312378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org *ok = false; 4313378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org return NULL; 4314378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 4315378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if (dupe_loc.IsValid()) { 4316378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ReportMessageAt(dupe_loc, "strict_param_dupe", 4317378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Vector<const char*>::empty()); 4318378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org *ok = false; 4319378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org return NULL; 4320378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 432104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (name_is_strict_reserved) { 4322394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int start_pos = scope->start_position(); 4323a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int position = function_token_pos != RelocInfo::kNoPosition 4324a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); 432583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Scanner::Location location = Scanner::Location(position, start_pos); 432683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ReportMessageAt(location, "strict_reserved_word", 432783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Vector<const char*>::empty()); 432883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org *ok = false; 432983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org return NULL; 433083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 433183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (reserved_loc.IsValid()) { 433283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ReportMessageAt(reserved_loc, "strict_reserved_word", 433383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Vector<const char*>::empty()); 433483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org *ok = false; 433583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org return NULL; 433683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 4337394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com CheckOctalLiteral(scope->start_position(), 4338394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->end_position(), 4339394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com CHECK_OK); 43400a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 4341b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org ast_properties = *factory()->visitor()->ast_properties(); 43422c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); 434344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 43440a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 43451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (is_extended_mode()) { 43461805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org CheckConflictingVarDeclarations(scope, CHECK_OK); 43471805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 43481805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 434944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org FunctionLiteral* function_literal = 4350b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewFunctionLiteral(function_name, 4351b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org scope, 4352b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org body, 4353b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org materialized_literal_count, 4354b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org expected_property_count, 4355b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org handler_count, 4356b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org num_parameters, 435756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org duplicate_parameters, 4358dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org function_type, 4359471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FunctionLiteral::kIsFunction, 4360f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org parenthesized, 4361a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org generator, 4362a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org pos); 4363a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org function_literal->set_function_token_position(function_token_pos); 4364b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org function_literal->set_ast_properties(&ast_properties); 43652c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org function_literal->set_dont_optimize_reason(dont_optimize_reason); 43665d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org 43677c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 436844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return function_literal; 436943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 437043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 437143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4372a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgPreParser::PreParseResult Parser::LazyParseFunctionLiteral( 43731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SingletonLogger* logger) { 43741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); 43751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT_EQ(Token::LBRACE, scanner().current_token()); 43761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 43771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (reusable_preparser_ == NULL) { 43781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org intptr_t stack_limit = isolate()->stack_guard()->real_climit(); 4379a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); 4380e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); 4381e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_modules(allow_modules()); 4382e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); 4383e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_lazy(true); 4384e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_generators(allow_generators()); 43851fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org reusable_preparser_->set_allow_for_of(allow_for_of()); 4386ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org reusable_preparser_->set_allow_harmony_numeric_literals( 4387ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org allow_harmony_numeric_literals()); 43881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 4389a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org PreParser::PreParseResult result = 43901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), 4391f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org is_generator(), 43921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org logger); 43931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return result; 43941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org} 43951b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 43961b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 439743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseV8Intrinsic(bool* ok) { 439843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // CallRuntime :: 439943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '%' Identifier Arguments 440043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4401a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = peek_position(); 440243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::MOD, CHECK_OK); 440343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> name = ParseIdentifier(CHECK_OK); 440443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 4405d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 4406d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (extension_ != NULL) { 440743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The extension structures are only accessible while parsing the 440843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // very first time not when reparsing because of lazy compilation. 44094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org top_scope_->DeclarationScope()->ForceEagerCompilation(); 441043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 441143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 44124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org const Runtime::Function* function = Runtime::FunctionForName(name); 441343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4414d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Check for built-in IS_VAR macro. 4415d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (function != NULL && 4416d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->intrinsic_type == Runtime::RUNTIME && 4417d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->function_id == Runtime::kIS_VAR) { 4418d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // %IS_VAR(x) evaluates to x if x is a variable, 4419d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // leads to a parse error otherwise. Could be implemented as an 4420d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // inline function %_IS_VAR(x) to eliminate this special case. 4421d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { 4422d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com return args->at(0); 4423d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } else { 4424f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ReportMessage("not_isvar", Vector<const char*>::empty()); 4425d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com *ok = false; 442643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 442743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 442843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 442943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4430d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Check that the expected number of arguments are being passed. 4431d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (function != NULL && 4432d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->nargs != -1 && 4433d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->nargs != args->length()) { 4434d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com ReportMessage("illegal_access", Vector<const char*>::empty()); 4435d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com *ok = false; 4436d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com return NULL; 4437de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org } 4438de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 4439de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org // Check that the function is defined if it's an inline runtime call. 4440de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org if (function == NULL && name->Get(0) == '_') { 4441de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); 4442de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org *ok = false; 4443de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org return NULL; 4444f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } 4445f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 4446d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // We have a valid intrinsics call or a call to a builtin. 4447a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewCallRuntime(name, function, args, pos); 444843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 444943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 445043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4451a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgbool ParserBase::peek_any_identifier() { 445283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Token::Value next = peek(); 445383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org return next == Token::IDENTIFIER || 445404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org next == Token::FUTURE_RESERVED_WORD || 4455f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org next == Token::FUTURE_STRICT_RESERVED_WORD || 4456f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org next == Token::YIELD; 445783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org} 445883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 445983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 4460b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgbool ParserBase::CheckContextualKeyword(Vector<const char> keyword) { 44611fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org if (peek() == Token::IDENTIFIER && 4462b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org scanner()->is_next_contextual_keyword(keyword)) { 44631fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Consume(Token::IDENTIFIER); 44641fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return true; 44651fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 44661fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return false; 44671fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org} 44681fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 44691fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 4470a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgvoid ParserBase::ExpectSemicolon(bool* ok) { 447143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check for automatic semicolon insertion according to 447243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // the rules given in ECMA-262, section 7.9, page 21. 447343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value tok = peek(); 447443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tok == Token::SEMICOLON) { 447543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 447643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 447743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 4478a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org if (scanner()->HasAnyLineTerminatorBeforeNext() || 447943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tok == Token::RBRACE || 448043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tok == Token::EOS) { 448143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 448243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 448343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SEMICOLON, ok); 448443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 448543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 448643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4487b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgvoid ParserBase::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { 4488812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Expect(Token::IDENTIFIER, ok); 4489812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org if (!*ok) return; 4490b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org if (!scanner()->is_literal_contextual_keyword(keyword)) { 4491b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org ReportUnexpectedToken(scanner()->current_token()); 4492812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org *ok = false; 4493812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 4494812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 4495812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 4496812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 4497a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgLiteral* Parser::GetLiteralUndefined(int position) { 4498a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewLiteral( 4499a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org isolate()->factory()->undefined_value(), position); 450043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 450143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 450243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4503a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgLiteral* Parser::GetLiteralTheHole(int position) { 4504a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewLiteral( 4505a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); 450643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 450743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 450843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4509b645116853c677aca8a316381b87441ba6004f67danno@chromium.org// Parses an identifier that is valid for the current scope, in particular it 451004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// fails on strict mode future reserved keywords in a strict scope. 451143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<String> Parser::ParseIdentifier(bool* ok) { 4512f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Token::Value next = Next(); 4513f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (next == Token::IDENTIFIER || 4514f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org (top_scope_->is_classic_mode() && 4515f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org (next == Token::FUTURE_STRICT_RESERVED_WORD || 4516f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org (next == Token::YIELD && !is_generator())))) { 4517bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org return GetSymbol(); 4518f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } else { 4519f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ReportUnexpectedToken(next); 4520f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org *ok = false; 4521f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return Handle<String>(); 452204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 452383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org} 452483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 452583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 452604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// Parses and identifier or a strict mode future reserved word, and indicate 452704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// whether it is strict mode future reserved. 452804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgHandle<String> Parser::ParseIdentifierOrStrictReservedWord( 452904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool* is_strict_reserved, bool* ok) { 4530f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Token::Value next = Next(); 4531f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (next == Token::IDENTIFIER) { 4532f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org *is_strict_reserved = false; 4533f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || 4534f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org (next == Token::YIELD && !is_generator())) { 453504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org *is_strict_reserved = true; 4536f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } else { 4537f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ReportUnexpectedToken(next); 4538f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org *ok = false; 4539f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return Handle<String>(); 454083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 4541bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org return GetSymbol(); 454243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 454343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4544d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org 4545d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.orgHandle<String> Parser::ParseIdentifierName(bool* ok) { 4546d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org Token::Value next = Next(); 454783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (next != Token::IDENTIFIER && 454804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org next != Token::FUTURE_RESERVED_WORD && 454904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org next != Token::FUTURE_STRICT_RESERVED_WORD && 455004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org !Token::IsKeyword(next)) { 4551d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org ReportUnexpectedToken(next); 4552d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org *ok = false; 4553d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org return Handle<String>(); 4554d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org } 4555bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org return GetSymbol(); 4556d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org} 4557d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org 4558378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 455964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid Parser::MarkAsLValue(Expression* expression) { 456064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org VariableProxy* proxy = expression != NULL 456164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ? expression->AsVariableProxy() 456264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org : NULL; 456364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 456464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (proxy != NULL) proxy->MarkAsLValue(); 456564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 456664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 456764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 4568378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Checks LHS expression for assignment and prefix/postfix increment/decrement 4569378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// in strict mode. 4570378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid Parser::CheckStrictModeLValue(Expression* expression, 4571378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org const char* error, 4572378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org bool* ok) { 45731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(!top_scope_->is_classic_mode()); 4574378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org VariableProxy* lhs = expression != NULL 4575378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ? expression->AsVariableProxy() 4576378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org : NULL; 4577378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 4578378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { 4579378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ReportMessage(error, Vector<const char*>::empty()); 4580378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org *ok = false; 4581378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 4582378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org} 4583378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 4584378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 45851c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org// Checks whether an octal literal was last seen between beg_pos and end_pos. 45861c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org// If so, reports an error. Only called for strict mode. 4587b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgvoid ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { 4588b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Scanner::Location octal = scanner()->octal_position(); 4589b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { 4590b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org ReportMessageAt(octal, "strict_octal_literal"); 4591b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org scanner()->clear_octal_position(); 45920ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org *ok = false; 45930ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 45940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org} 45950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4596d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org 45971805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { 45981805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Declaration* decl = scope->CheckConflictingVarDeclarations(); 45991805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org if (decl != NULL) { 46001805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // In harmony mode we treat conflicting variable bindinds as early 46011805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // errors. See ES5 16 for a definition of early errors. 46021805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Handle<String> name = decl->proxy()->name(); 460383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); 46041805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org const char* elms[2] = { "Variable", *c_string }; 46051805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Vector<const char*> args(elms, 2); 46061805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org int position = decl->proxy()->position(); 46071805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Scanner::Location location = position == RelocInfo::kNoPosition 46081805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org ? Scanner::Location::invalid() 46091805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org : Scanner::Location(position, position + 1); 46101805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org ReportMessageAt(location, "redeclaration", args); 46111805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org *ok = false; 46121805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 46131805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org} 46141805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 46151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 461604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// This function reads an identifier name and determines whether or not it 461783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// is 'get' or 'set'. 461804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgHandle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, 461904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool* is_set, 462004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool* ok) { 462104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org Handle<String> result = ParseIdentifierName(ok); 462243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!*ok) return Handle<String>(); 46239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { 46249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org const char* token = scanner().literal_ascii_string().start(); 46259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *is_get = strncmp(token, "get", 3) == 0; 46269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *is_set = !*is_get && strncmp(token, "set", 3) == 0; 462743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 462883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org return result; 462943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 463043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 463143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 463243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 463343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Parser support 463443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 463543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 463643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Parser::TargetStackContainsLabel(Handle<String> label) { 4637b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != NULL; t = t->previous()) { 4638b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org BreakableStatement* stat = t->node()->AsBreakableStatement(); 463943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (stat != NULL && ContainsLabel(stat->labels(), label)) 464043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 464143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 464243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 464343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 464443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 464543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 464643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenBreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { 464743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool anonymous = label.is_null(); 4648b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != NULL; t = t->previous()) { 4649b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org BreakableStatement* stat = t->node()->AsBreakableStatement(); 465043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (stat == NULL) continue; 465143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if ((anonymous && stat->is_target_for_anonymous()) || 465243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen (!anonymous && ContainsLabel(stat->labels(), label))) { 4653b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org RegisterTargetUse(stat->break_target(), t->previous()); 465443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return stat; 465543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 465643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 465743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 465843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 465943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 466043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 466143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenIterationStatement* Parser::LookupContinueTarget(Handle<String> label, 466243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* ok) { 466343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool anonymous = label.is_null(); 4664b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != NULL; t = t->previous()) { 4665b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org IterationStatement* stat = t->node()->AsIterationStatement(); 466643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (stat == NULL) continue; 466743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 466843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(stat->is_target_for_anonymous()); 466943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (anonymous || ContainsLabel(stat->labels(), label)) { 4670b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org RegisterTargetUse(stat->continue_target(), t->previous()); 467143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return stat; 467243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 467343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 467443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 467543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 467643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 467743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 467844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid Parser::RegisterTargetUse(Label* target, Target* stop) { 4679b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org // Register that a break target found at the given stop in the 46807be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org // target stack has been used from the top of the target stack. Add 46817be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org // the break target to any TargetCollectors passed on the stack. 4682b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != stop; t = t->previous()) { 4683b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org TargetCollector* collector = t->node()->AsTargetCollector(); 46847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (collector != NULL) collector->AddTarget(target, zone()); 468543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 468643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 468743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 468843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4689dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgExpression* Parser::NewThrowReferenceError(Handle<String> message) { 46904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return NewThrowError(isolate()->factory()->MakeReferenceError_string(), 4691dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org message, HandleVector<Object>(NULL, 0)); 469243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 469343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 469443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4695dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgExpression* Parser::NewThrowSyntaxError(Handle<String> message, 469643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> first) { 469743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int argc = first.is_null() ? 0 : 1; 469843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc); 4699ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return NewThrowError( 4700dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org isolate()->factory()->MakeSyntaxError_string(), message, arguments); 470143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 470243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 470343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4704dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgExpression* Parser::NewThrowTypeError(Handle<String> message, 470543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> first, 470643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> second) { 470743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(!first.is_null() && !second.is_null()); 470843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> elements[] = { first, second }; 470943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Vector< Handle<Object> > arguments = 471043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HandleVector<Object>(elements, ARRAY_SIZE(elements)); 4711ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return NewThrowError( 4712dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org isolate()->factory()->MakeTypeError_string(), message, arguments); 471343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 471443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 471543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 471643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::NewThrowError(Handle<String> constructor, 4717dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message, 471843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Vector< Handle<Object> > arguments) { 471943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int argc = arguments.length(); 4720ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc, 4721ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org TENURED); 472243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < argc; i++) { 472343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> element = arguments[i]; 472443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!element.is_null()) { 4725496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org elements->set(i, *element); 472643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 472743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 4728fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements( 4729fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org elements, FAST_ELEMENTS, TENURED); 4730496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 4731a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int pos = position(); 47327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone()); 4733a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org args->Add(factory()->NewLiteral(message, pos), zone()); 4734a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org args->Add(factory()->NewLiteral(array, pos), zone()); 4735b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org CallRuntime* call_constructor = 4736a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org factory()->NewCallRuntime(constructor, NULL, args, pos); 4737a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org return factory()->NewThrow(call_constructor, pos); 473843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 473943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4740e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 4741b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// ---------------------------------------------------------------------------- 4742a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Regular expressions 4743a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4744a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4745a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpParser::RegExpParser(FlatStringReader* in, 4746a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Handle<String>* error, 47475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org bool multiline, 47485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Zone* zone) 47493d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org : isolate_(zone->isolate()), 47505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org zone_(zone), 4751ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org error_(error), 4752ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org captures_(NULL), 4753ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org in_(in), 4754ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org current_(kEndMarker), 4755ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org next_pos_(0), 4756ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org capture_count_(0), 4757ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org has_more_(true), 4758ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org multiline_(multiline), 4759ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org simple_(false), 4760ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org contains_anchor_(false), 4761ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org is_scanned_for_captures_(false), 4762ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org failed_(false) { 4763023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org Advance(); 4764a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4765a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4766a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4767a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::Next() { 4768a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (has_next()) { 4769a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return in()->Get(next_pos_); 4770a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4771a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return kEndMarker; 4772a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4773a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4774a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4775a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4776a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Advance() { 4777a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (next_pos_ < in()->length()) { 4778ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org StackLimitCheck check(isolate()); 4779a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (check.HasOverflowed()) { 4780ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ReportError(CStrVector(Isolate::kStackOverflowMessage)); 47815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else if (zone()->excess_allocation()) { 4782a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ReportError(CStrVector("Regular expression too large")); 4783a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4784a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org current_ = in()->Get(next_pos_); 4785a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org next_pos_++; 4786a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4787a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 4788a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org current_ = kEndMarker; 4789a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org has_more_ = false; 4790a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4791a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4792a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4793a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4794a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Reset(int pos) { 4795a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org next_pos_ = pos; 479653ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org has_more_ = (pos < in()->length()); 4797a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4798a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4799a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4800a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4801a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Advance(int dist) { 4802023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org next_pos_ += dist - 1; 4803023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org Advance(); 4804a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4805a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4806a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 480737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.combool RegExpParser::simple() { 480837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return simple_; 4809a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4810a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4811e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 4812a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ReportError(Vector<const char> message) { 4813a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org failed_ = true; 4814ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED); 4815a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Zip to the end to make sure the no more input is read. 4816a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org current_ = kEndMarker; 4817a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org next_pos_ = in()->length(); 4818a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return NULL; 4819a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4820a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4821a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4822a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Pattern :: 4823a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Disjunction 4824a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParsePattern() { 4825a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpTree* result = ParseDisjunction(CHECK_FAILED); 482686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ASSERT(!has_more()); 48277ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org // If the result of parsing is a literal string atom, and it has the 48287ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org // same length as the input, then the atom is identical to the input. 48297ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org if (result->IsAtom() && result->AsAtom()->length() == in()->length()) { 48307ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org simple_ = true; 48317ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org } 4832a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return result; 4833a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 4834a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4835a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4836a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Disjunction :: 4837a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Alternative 4838a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Alternative | Disjunction 4839a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Alternative :: 4840a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// [empty] 4841a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Term Alternative 4842a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Term :: 4843a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Assertion 4844a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Atom 4845a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Atom Quantifier 4846a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParseDisjunction() { 484786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Used to store current state while parsing subexpressions. 4848400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org RegExpParserState initial_state(NULL, INITIAL, 0, zone()); 484986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpParserState* stored_state = &initial_state; 485086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Cache the builder in a local variable for quick access. 485186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpBuilder* builder = initial_state.builder(); 4852a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (true) { 4853a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (current()) { 4854a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case kEndMarker: 485586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (stored_state->IsSubexpression()) { 485686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Inside a parenthesized group when hitting end of input. 485786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Unterminated group") CHECK_FAILED); 485886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 485986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ASSERT_EQ(INITIAL, stored_state->group_type()); 486086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Parsing completed successfully. 486186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org return builder->ToRegExp(); 486286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case ')': { 486386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (!stored_state->IsSubexpression()) { 486486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Unmatched ')'") CHECK_FAILED); 486586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 486686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ASSERT_NE(INITIAL, stored_state->group_type()); 486786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 4868a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 486986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // End disjunction parsing and convert builder content to new single 487086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // regexp atom. 487186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpTree* body = builder->ToRegExp(); 487286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 487386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org int end_capture_index = captures_started(); 487486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 487586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org int capture_index = stored_state->capture_index(); 4876dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org SubexpressionType group_type = stored_state->group_type(); 487786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 487886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Restore previous state. 487986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org stored_state = stored_state->previous_state(); 488086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder = stored_state->builder(); 488186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 488286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Build result of subexpression. 4883dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org if (group_type == CAPTURE) { 4884c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index); 488586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org captures_->at(capture_index - 1) = capture; 488686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org body = capture; 4887dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org } else if (group_type != GROUPING) { 4888dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org ASSERT(group_type == POSITIVE_LOOKAHEAD || 4889dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org group_type == NEGATIVE_LOOKAHEAD); 4890dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org bool is_positive = (group_type == POSITIVE_LOOKAHEAD); 4891c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org body = new(zone()) RegExpLookahead(body, 489286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org is_positive, 489386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org end_capture_index - capture_index, 489486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org capture_index); 4895a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 489686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(body); 489749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // For compatability with JSC and ES3, we allow quantifiers after 489849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // lookaheads, and break in all cases. 489986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 490086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 490186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case '|': { 490286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Advance(); 490386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->NewAlternative(); 4904a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 4905a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4906a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '*': 4907a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '+': 4908a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '?': 4909e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return ReportError(CStrVector("Nothing to repeat")); 4910a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '^': { 4911a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4912245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (multiline_) { 491386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 4914c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE)); 4915245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } else { 491686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 4917c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT)); 4918245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org set_contains_anchor(); 4919245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 4920a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 4921a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4922a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '$': { 4923a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4924dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org RegExpAssertion::AssertionType assertion_type = 4925a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org multiline_ ? RegExpAssertion::END_OF_LINE : 4926a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpAssertion::END_OF_INPUT; 4927dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type)); 4928a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 4929a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4930a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '.': { 4931a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 4932a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // everything except \x0a, \x0d, \u2028 and \u2029 493340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org ZoneList<CharacterRange>* ranges = 49347028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<CharacterRange>(2, zone()); 49357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange::AddClassEscape('.', ranges, zone()); 4936c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); 493786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 4938a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4939a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4940a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '(': { 4941dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org SubexpressionType subexpr_type = CAPTURE; 494286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Advance(); 494386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (current() == '?') { 494486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org switch (Next()) { 494586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case ':': 4946dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org subexpr_type = GROUPING; 494786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 494886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case '=': 4949dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org subexpr_type = POSITIVE_LOOKAHEAD; 495086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 495186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case '!': 4952dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org subexpr_type = NEGATIVE_LOOKAHEAD; 495386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 495486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org default: 495586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Invalid group") CHECK_FAILED); 495686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 495786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 495886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Advance(2); 495986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } else { 496086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (captures_ == NULL) { 49617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone()); 496286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 496386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (captures_started() >= kMaxCaptures) { 496486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Too many captures") CHECK_FAILED); 496586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 49667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org captures_->Add(NULL, zone()); 496786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 496886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Store current state and begin new disjunction parsing. 4969dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type, 4970400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org captures_started(), zone()); 497186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder = stored_state->builder(); 497249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org continue; 4973a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4974a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '[': { 4975a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpTree* atom = ParseCharacterClass(CHECK_FAILED); 497686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 4977a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 4978a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 4979a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Atom :: 4980a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // \ AtomEscape 4981a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '\\': 4982a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (Next()) { 4983a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case kEndMarker: 4984e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return ReportError(CStrVector("\\ at end of pattern")); 4985a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'b': 4986a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 498786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 4988c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY)); 4989a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 4990a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'B': 4991a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 499286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 4993c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY)); 4994a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 499549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // AtomEscape :: 499649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // CharacterClassEscape 499749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // 499849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // CharacterClassEscape :: one of 499949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // d D s S w W 5000a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'd': case 'D': case 's': case 'S': case 'w': case 'W': { 5001a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = Next(); 5002a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 500340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org ZoneList<CharacterRange>* ranges = 50047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<CharacterRange>(2, zone()); 50057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange::AddClassEscape(c, ranges, zone()); 5006c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); 500786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 500886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 5009a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5010a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '1': case '2': case '3': case '4': case '5': case '6': 5011a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '7': case '8': case '9': { 5012a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int index = 0; 5013a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseBackReferenceIndex(&index)) { 501486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpCapture* capture = NULL; 501586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (captures_ != NULL && index <= captures_->length()) { 501686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org capture = captures_->at(index - 1); 501786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 501886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (capture == NULL) { 501986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddEmpty(); 502086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 5021a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5022c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpTree* atom = new(zone()) RegExpBackReference(capture); 502386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 502486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 5025a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5026a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 first_digit = Next(); 5027a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (first_digit == '8' || first_digit == '9') { 5028a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Treat as identity escape 502986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(first_digit); 5030a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5031a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5032a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5033a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5034a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // FALLTHROUGH 5035a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '0': { 5036a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5037a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 octal = ParseOctalLiteral(); 503886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(octal); 5039a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5040a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5041a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // ControlEscape :: one of 5042a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // f n r t v 5043a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'f': 5044a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 504586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\f'); 5046a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5047a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'n': 5048a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 504986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\n'); 5050a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5051a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'r': 5052a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 505386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\r'); 5054a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5055a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 't': 5056a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 505786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\t'); 5058a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5059a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'v': 5060a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 506186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\v'); 5062a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5063a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'c': { 5064d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Advance(); 5065d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 controlLetter = Next(); 5066d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Special case if it is an ASCII letter. 5067d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Convert lower case letters to uppercase. 5068d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 letter = controlLetter & ~('a' ^ 'A'); 5069d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if (letter < 'A' || 'Z' < letter) { 5070d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // controlLetter is not in range 'A'-'Z' or 'a'-'z'. 5071d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // This is outside the specification. We match JSC in 5072d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // reading the backslash as a literal character instead 5073d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // of as starting an escape. 5074d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org builder->AddCharacter('\\'); 5075d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } else { 5076d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Advance(2); 5077d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org builder->AddCharacter(controlLetter & 0x1f); 5078d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 5079a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5080a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5081a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'x': { 5082a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5083a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 5084a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(2, &value)) { 508586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(value); 5086a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 508786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('x'); 5088a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5089a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5090a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5091a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'u': { 5092a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5093a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 5094a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(4, &value)) { 509586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(value); 5096a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 509786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('u'); 5098a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5099a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5100a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5101a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 5102a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Identity escape. 510386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(Next()); 5104a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5105a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5106a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5107a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5108a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '{': { 5109a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int dummy; 5110a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseIntervalQuantifier(&dummy, &dummy)) { 5111a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ReportError(CStrVector("Nothing to repeat") CHECK_FAILED); 5112a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5113a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // fallthrough 5114a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5115a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 511686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(current()); 5117a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5118a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5119a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } // end switch(current()) 5120a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5121a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int min; 5122a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int max; 5123a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (current()) { 5124a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // QuantifierPrefix :: 5125a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // * 5126a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // + 5127a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // ? 5128a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // { 5129a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '*': 5130a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org min = 0; 513137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com max = RegExpTree::kInfinity; 5132a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5133a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5134a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '+': 5135a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org min = 1; 513637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com max = RegExpTree::kInfinity; 5137a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5138a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5139a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '?': 5140a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org min = 0; 5141a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org max = 1; 5142a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5143a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5144a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '{': 5145a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseIntervalQuantifier(&min, &max)) { 5146245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (max < min) { 5147245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org ReportError(CStrVector("numbers out of order in {} quantifier.") 5148245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org CHECK_FAILED); 5149245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 5150a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5151a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5152a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 5153a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5154a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 5155a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 5156a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5157dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY; 5158a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '?') { 5159dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org quantifier_type = RegExpQuantifier::NON_GREEDY; 51600c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Advance(); 51610c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } else if (FLAG_regexp_possessive_quantifier && current() == '+') { 51620c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // FLAG_regexp_possessive_quantifier is a debug-only flag. 5163dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org quantifier_type = RegExpQuantifier::POSSESSIVE; 5164a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5165a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5166dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org builder->AddQuantifierToAtom(min, max, quantifier_type); 5167a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5168a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5169a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5170a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5171a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifdef DEBUG 5172a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Currently only used in an ASSERT. 5173a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatic bool IsSpecialClassEscape(uc32 c) { 5174a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (c) { 5175a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'd': case 'D': 5176a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 's': case 'S': 5177a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'w': case 'W': 5178a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 5179a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 5180a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5181a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5182a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5183a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif 5184a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5185a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5186a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// In order to know whether an escape is a backreference or not we have to scan 5187a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// the entire regexp and find the number of capturing parentheses. However we 5188a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// don't want to scan the regexp twice unless it is necessary. This mini-parser 5189a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// is called when needed. It can see the difference between capturing and 5190a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// noncapturing parentheses and can skip character classes and backslash-escaped 5191a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// characters. 5192a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::ScanForCaptures() { 5193a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Start with captures started previous to current position 5194a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int capture_count = captures_started(); 5195a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Add count of captures after this position. 5196a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int n; 5197a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while ((n = current()) != kEndMarker) { 5198a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5199a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (n) { 5200a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '\\': 5201a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5202a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5203a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '[': { 5204a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int c; 5205a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while ((c = current()) != kEndMarker) { 5206a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5207a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (c == '\\') { 5208a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5209a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5210a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (c == ']') break; 5211a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5212a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5213a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5214a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5215a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '(': 5216a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() != '?') capture_count++; 5217a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5218a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5219a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5220a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org capture_count_ = capture_count; 5221a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org is_scanned_for_captures_ = true; 5222a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5223a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5224a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5225a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseBackReferenceIndex(int* index_out) { 5226a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT_EQ('\\', current()); 5227a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT('1' <= Next() && Next() <= '9'); 5228245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // Try to parse a decimal literal that is no greater than the total number 5229245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // of left capturing parentheses in the input. 5230a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int start = position(); 5231a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int value = Next() - '0'; 5232a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5233a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (true) { 5234a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = current(); 5235a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (IsDecimalDigit(c)) { 5236a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org value = 10 * value + (c - '0'); 5237245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (value > kMaxCaptures) { 5238245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org Reset(start); 5239245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org return false; 5240245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 5241a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5242a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5243a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5244a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5245a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5246a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (value > captures_started()) { 5247a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!is_scanned_for_captures_) { 5248a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int saved_position = position(); 5249a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ScanForCaptures(); 5250a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(saved_position); 5251a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5252a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (value > capture_count_) { 5253a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 5254a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5255a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5256a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5257a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *index_out = value; 5258a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 5259a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5260a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5261a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5262a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// QuantifierPrefix :: 5263a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// { DecimalDigits } 5264a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// { DecimalDigits , } 5265a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// { DecimalDigits , DecimalDigits } 5266245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// 5267245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// Returns true if parsing succeeds, and set the min_out and max_out 5268245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// values. Values are truncated to RegExpTree::kInfinity if they overflow. 5269a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) { 5270a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT_EQ(current(), '{'); 5271a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int start = position(); 5272a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5273a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int min = 0; 5274a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!IsDecimalDigit(current())) { 5275a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 5276a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5277a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5278a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (IsDecimalDigit(current())) { 5279245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org int next = current() - '0'; 5280245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (min > (RegExpTree::kInfinity - next) / 10) { 5281245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // Overflow. Skip past remaining decimal digits and return -1. 5282245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org do { 5283245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org Advance(); 5284245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } while (IsDecimalDigit(current())); 5285245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org min = RegExpTree::kInfinity; 5286245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org break; 5287245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 5288245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org min = 10 * min + next; 5289a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5290a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5291a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int max = 0; 5292a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '}') { 5293a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org max = min; 5294a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5295a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (current() == ',') { 5296a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5297a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '}') { 529837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com max = RegExpTree::kInfinity; 5299a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5300a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5301a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (IsDecimalDigit(current())) { 5302245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org int next = current() - '0'; 5303245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (max > (RegExpTree::kInfinity - next) / 10) { 5304245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org do { 5305245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org Advance(); 5306245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } while (IsDecimalDigit(current())); 5307245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org max = RegExpTree::kInfinity; 5308245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org break; 5309245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 5310245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org max = 10 * max + next; 5311a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5312a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5313a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() != '}') { 5314a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 5315a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5316a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5317a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5318a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5319a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5320a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 5321a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5322a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5323a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *min_out = min; 5324a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *max_out = max; 5325a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 5326a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5327a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5328a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5329a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::ParseOctalLiteral() { 5330a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT('0' <= current() && current() <= '7'); 5331a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // For compatibility with some other browsers (not all), we parse 5332a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // up to three octal digits with a value below 256. 5333a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value = current() - '0'; 5334a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5335a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if ('0' <= current() && current() <= '7') { 5336a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org value = value * 8 + current() - '0'; 5337a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5338a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (value < 32 && '0' <= current() && current() <= '7') { 5339a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org value = value * 8 + current() - '0'; 5340a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5341a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5342a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5343a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return value; 5344a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5345a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5346a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5347a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseHexEscape(int length, uc32 *value) { 5348a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int start = position(); 5349a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 val = 0; 5350a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org bool done = false; 5351a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org for (int i = 0; !done; i++) { 5352a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = current(); 5353a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int d = HexValue(c); 5354a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (d < 0) { 5355a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 5356a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5357a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5358a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org val = val * 16 + d; 5359a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5360a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (i == length - 1) { 5361a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org done = true; 5362a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5363a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5364a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *value = val; 5365a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 5366a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5367a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5368a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5369a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::ParseClassCharacterEscape() { 5370a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(current() == '\\'); 5371a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(has_next() && !IsSpecialClassEscape(Next())); 5372a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5373a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (current()) { 5374a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'b': 5375a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5376a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\b'; 5377a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // ControlEscape :: one of 5378a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // f n r t v 5379a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'f': 5380a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5381a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\f'; 5382a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'n': 5383a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5384a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\n'; 5385a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'r': 5386a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5387a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\r'; 5388a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 't': 5389a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5390a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\t'; 5391a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'v': 5392a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5393a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\v'; 5394d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org case 'c': { 5395d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 controlLetter = Next(); 5396d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 letter = controlLetter & ~('A' ^ 'a'); 5397d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // For compatibility with JSC, inside a character class 5398d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // we also accept digits and underscore as control characters. 5399d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if ((controlLetter >= '0' && controlLetter <= '9') || 5400d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org controlLetter == '_' || 5401d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org (letter >= 'A' && letter <= 'Z')) { 5402d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Advance(2); 5403d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Control letters mapped to ASCII control characters in the range 5404d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // 0x00-0x1f. 5405d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org return controlLetter & 0x1f; 5406d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 5407d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // We match JSC in reading the backslash as a literal 5408d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // character instead of as starting an escape. 5409d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org return '\\'; 5410d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 5411a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '0': case '1': case '2': case '3': case '4': case '5': 5412a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '6': case '7': 5413a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // For compatibility, we interpret a decimal escape that isn't 5414a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // a back reference (and therefore either \0 or not valid according 5415a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // to the specification) as a 1..3 digit octal character code. 5416a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return ParseOctalLiteral(); 5417a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'x': { 5418a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5419a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 5420a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(2, &value)) { 5421a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return value; 5422a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5423a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // If \x is not followed by a two-digit hexadecimal, treat it 5424a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // as an identity escape. 5425a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return 'x'; 5426a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5427a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'u': { 5428a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5429a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 5430a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(4, &value)) { 5431a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return value; 5432a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5433a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // If \u is not followed by a four-digit hexadecimal, treat it 5434a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // as an identity escape. 5435a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return 'u'; 5436a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5437a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: { 5438a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Extended identity escape. We accept any character that hasn't 5439a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // been matched by a more specific case, not just the subset required 5440a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // by the ECMAScript specification. 5441a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 result = current(); 5442a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5443a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return result; 5444a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5445a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5446a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return 0; 5447a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5448a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5449a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5450a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgCharacterRange RegExpParser::ParseClassAtom(uc16* char_class) { 5451a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT_EQ(0, *char_class); 5452a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 first = current(); 5453a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (first == '\\') { 5454a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (Next()) { 5455a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'w': case 'W': case 'd': case 'D': case 's': case 'S': { 5456a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *char_class = Next(); 5457a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5458a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return CharacterRange::Singleton(0); // Return dummy value. 5459a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 546037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com case kEndMarker: 5461e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return ReportError(CStrVector("\\ at end of pattern")); 5462a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 5463a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = ParseClassCharacterEscape(CHECK_FAILED); 5464a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return CharacterRange::Singleton(c); 5465a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5466a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5467a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5468a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return CharacterRange::Singleton(first); 5469a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5470a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5471a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5472a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 547314a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.orgstatic const uc16 kNoCharClass = 0; 547414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org 547514a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// Adds range or pre-defined character class to character ranges. 547614a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// If char_class is not kInvalidClass, it's interpreted as a class 547714a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// escape (i.e., 's' means whitespace, from '\s'). 547814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.orgstatic inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges, 547914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org uc16 char_class, 54807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange range, 54817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Zone* zone) { 548214a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org if (char_class != kNoCharClass) { 54837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange::AddClassEscape(char_class, ranges, zone); 548414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org } else { 54857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(range, zone); 548614a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org } 548714a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org} 548814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org 548914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org 5490a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParseCharacterClass() { 5491a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org static const char* kUnterminated = "Unterminated character class"; 5492a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org static const char* kRangeOutOfOrder = "Range out of order in character class"; 5493a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5494a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT_EQ(current(), '['); 5495a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5496a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org bool is_negated = false; 5497a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '^') { 5498a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org is_negated = true; 5499a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5500a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 55017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<CharacterRange>* ranges = 55027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<CharacterRange>(2, zone()); 5503a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (has_more() && current() != ']') { 550414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org uc16 char_class = kNoCharClass; 5505a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED); 5506a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '-') { 5507a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5508a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == kEndMarker) { 5509a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // If we reach the end we break out of the loop and let the 5510a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // following code report an error. 5511a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5512a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (current() == ']') { 55137028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class, first, zone()); 55147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Singleton('-'), zone()); 5515a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5516a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 551714a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org uc16 char_class_2 = kNoCharClass; 551814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED); 551914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org if (char_class != kNoCharClass || char_class_2 != kNoCharClass) { 552014a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org // Either end is an escaped character class. Treat the '-' verbatim. 55217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class, first, zone()); 55227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Singleton('-'), zone()); 55237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class_2, next, zone()); 552414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org continue; 5525a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5526a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (first.from() > next.to()) { 5527a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED); 5528a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 55297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Range(first.from(), next.to()), zone()); 5530a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 55317028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class, first, zone()); 5532a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5533a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5534a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!has_more()) { 5535a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return ReportError(CStrVector(kUnterminated) CHECK_FAILED); 5536a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5537a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5538a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ranges->length() == 0) { 55397028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Everything(), zone()); 5540a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org is_negated = !is_negated; 5541a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5542c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org return new(zone()) RegExpCharacterClass(ranges, is_negated); 5543a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5544a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5545a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5546a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// ---------------------------------------------------------------------------- 554743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The Parser interface. 554843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 554943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenScriptDataImpl::~ScriptDataImpl() { 55505b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org if (owns_store_) store_.Dispose(); 555143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 555243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 555343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 555443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint ScriptDataImpl::Length() { 55559155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org return store_.length() * sizeof(unsigned); 555643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 555743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 555843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 55599155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgconst char* ScriptDataImpl::Data() { 55609155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org return reinterpret_cast<const char*>(store_.start()); 556143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 556243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 556343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 55640c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgbool ScriptDataImpl::HasError() { 55650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return has_error(); 55660c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 55670c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 55680c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 5569d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.comvoid ScriptDataImpl::Initialize() { 5570c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // Prepares state for use. 5571beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (store_.length() >= PreparseDataConstants::kHeaderSize) { 5572beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org function_index_ = PreparseDataConstants::kHeaderSize; 5573beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org int symbol_data_offset = PreparseDataConstants::kHeaderSize 5574beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org + store_[PreparseDataConstants::kFunctionsSizeOffset]; 5575d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (store_.length() > symbol_data_offset) { 5576d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); 5577d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } else { 5578d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Partial preparse causes no symbol information. 5579d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 5580d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } 5581d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 5582d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } 5583d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com} 5584d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 5585d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 5586d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.comint ScriptDataImpl::ReadNumber(byte** source) { 5587d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Reads a number from symbol_data_ in base 128. The most significant 5588d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // bit marks that there are more digits. 5589d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // If the first byte is 0x80 (kNumberTerminator), it would normally 5590d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // represent a leading zero. Since that is useless, and therefore won't 5591d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // appear as the first digit of any actual value, it is used to 5592d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // mark the end of the input stream. 5593d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com byte* data = *source; 5594d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (data >= symbol_data_end_) return -1; 5595d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com byte input = *data; 5596beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (input == PreparseDataConstants::kNumberTerminator) { 5597d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // End of stream marker. 5598d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com return -1; 5599d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } 5600d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com int result = input & 0x7f; 5601d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com data++; 5602d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com while ((input & 0x80u) != 0) { 5603d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (data >= symbol_data_end_) return -1; 5604d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com input = *data; 5605d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com result = (result << 7) | (input & 0x7f); 5606d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com data++; 5607d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } 5608d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com *source = data; 5609d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com return result; 5610d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com} 5611d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 5612d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 561321b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org// Create a Scanner for the preparser to use as input, and preparse the source. 56143d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgScriptDataImpl* PreParserApi::PreParse(Isolate* isolate, 56153d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Utf16CharacterStream* source) { 5616e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CompleteParserRecorder recorder; 56171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org HistogramTimerScope timer(isolate->counters()->pre_parse()); 5618c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Scanner scanner(isolate->unicode_cache()); 5619ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org intptr_t stack_limit = isolate->stack_guard()->real_climit(); 5620a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org PreParser preparser(&scanner, &recorder, stack_limit); 5621e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org preparser.set_allow_lazy(true); 5622e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org preparser.set_allow_generators(FLAG_harmony_generators); 56231fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org preparser.set_allow_for_of(FLAG_harmony_iteration); 5624e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); 5625ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); 5626e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org scanner.Initialize(source); 5627a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org PreParser::PreParseResult result = preparser.PreParseProgram(); 5628a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org if (result == PreParser::kPreParseStackOverflow) { 5629ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate->StackOverflow(); 56304a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return NULL; 56314a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com } 56324a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 56334a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Extract the accumulated data from the recorder as a single 56344a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // contiguous vector that we are responsible for disposing. 5635e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Vector<unsigned> store = recorder.ExtractData(); 56364a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return new ScriptDataImpl(store); 56374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 56384a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 56394a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 5640e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgbool RegExpParser::ParseRegExp(FlatStringReader* input, 5641e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org bool multiline, 56425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org RegExpCompileData* result, 56435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Zone* zone) { 5644a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(result != NULL); 56455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org RegExpParser parser(input, &result->error, multiline, zone); 564637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com RegExpTree* tree = parser.ParsePattern(); 5647a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (parser.failed()) { 564837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com ASSERT(tree == NULL); 5649a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(!result->error.is_null()); 5650a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 565137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com ASSERT(tree != NULL); 5652a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(result->error.is_null()); 565337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result->tree = tree; 565437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com int capture_count = parser.captures_started(); 565537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; 5656245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org result->contains_anchor = parser.contains_anchor(); 565737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result->capture_count = capture_count; 5658a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5659a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return !parser.failed(); 5660a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5661a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5662a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5663e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool Parser::Parse() { 5664e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(info()->function() == NULL); 5665b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org FunctionLiteral* result = NULL; 5666e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (info()->is_lazy()) { 5667e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!info()->is_eval()); 5668e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (info()->shared_info()->is_function()) { 5669e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org result = ParseLazy(); 567056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org } else { 5671e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org result = ParseProgram(); 567256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org } 5673b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 5674e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); 5675e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_pre_parse_data(pre_parse_data); 5676e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (pre_parse_data != NULL && pre_parse_data->has_error()) { 5677e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Scanner::Location loc = pre_parse_data->MessageLocation(); 5678e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const char* message = pre_parse_data->BuildMessage(); 5679e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Vector<const char*> args = pre_parse_data->BuildArgs(); 5680e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ReportMessageAt(loc, message, args); 5681b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org DeleteArray(message); 5682b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org for (int i = 0; i < args.length(); i++) { 5683b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org DeleteArray(args[i]); 5684b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org } 5685b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org DeleteArray(args.start()); 5686e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(info()->isolate()->has_pending_exception()); 5687b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org } else { 5688e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org result = ParseProgram(); 5689b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org } 5690b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 5691e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org info()->SetFunction(result); 5692b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org return (result != NULL); 569343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 569443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 569543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 5696