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) 5395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org : isolate_(info->isolate()), 540e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org symbol_cache_(0, info->zone()), 5415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org script_(info->script()), 542a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org scanner_(isolate_->unicode_cache()), 5431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org reusable_preparser_(NULL), 54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen top_scope_(NULL), 545c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org current_function_state_(NULL), 54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen target_stack_(NULL), 547e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org extension_(info->extension()), 548e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org pre_parse_data_(NULL), 549a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org fni_(NULL), 550e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org allow_natives_syntax_(false), 551e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org allow_lazy_(false), 552e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org allow_generators_(false), 5531fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org allow_for_of_(false), 554c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org stack_overflow_(false), 555400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org parenthesized_function_(false), 5565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org zone_(info->zone()), 5575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org info_(info) { 5585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(!script_.is_null()); 55956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org isolate_->set_ast_node_id(0); 560e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); 561e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_modules(!info->is_native() && FLAG_harmony_modules); 562e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); 563e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_lazy(false); // Must be explicitly enabled. 564e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_allow_generators(FLAG_harmony_generators); 5651fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org set_allow_for_of(FLAG_harmony_iteration); 566ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); 56743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 56843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 56943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgFunctionLiteral* Parser::ParseProgram() { 5717979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org HistogramTimerScope timer(isolate()->counters()->parse()); 57227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Handle<String> source(String::cast(script_->source())); 5737979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org isolate()->counters()->total_parse_size()->Increment(source->length()); 574304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org int64_t start = FLAG_trace_parse ? OS::Ticks() : 0; 5757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); 57643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 57743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize parser state. 578ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org source->TryFlatten(); 579304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FunctionLiteral* result; 5805f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org if (source->IsExternalTwoByteString()) { 5815f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Notice that the stream is destroyed at the end of the branch block. 5825f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // The last line of the blocks can't be moved outside, even though they're 5835f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // identical calls. 584154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ExternalTwoByteStringUtf16CharacterStream stream( 5855f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 5869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org scanner_.Initialize(&stream); 5871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org result = DoParseProgram(info(), source); 5885f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else { 589154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org GenericStringUtf16CharacterStream stream(source, 0, source->length()); 5909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org scanner_.Initialize(&stream); 5911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org result = DoParseProgram(info(), source); 5925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 593304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 594304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (FLAG_trace_parse && result != NULL) { 595304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org double ms = static_cast<double>(OS::Ticks() - start) / 1000; 596304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (info()->is_eval()) { 597304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF("[parsing eval"); 598304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } else if (info()->script()->name()->IsString()) { 599304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org String* name = String::cast(info()->script()->name()); 600304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org SmartArrayPointer<char> name_chars = name->ToCString(); 601304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF("[parsing script: %s", *name_chars); 602304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } else { 603304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF("[parsing script"); 604304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 605304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF(" - took %0.3f ms]\n", ms); 606304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 607304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org return result; 6085f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 6095f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 6105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 61127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgFunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, 6121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> source) { 613394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(top_scope_ == NULL); 61443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(target_stack_ == NULL); 615e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); 61643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<String> no_name = isolate()->factory()->empty_string(); 61843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FunctionLiteral* result = NULL; 62027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 62127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org info->SetGlobalScope(scope); 622355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org if (!info->context().is_null()) { 623355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); 624355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org } 6252c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (info->is_eval()) { 6262c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { 6272c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org scope = NewScope(scope, EVAL_SCOPE); 6282c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } 629355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org } else if (info->is_global()) { 630355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org scope = NewScope(scope, GLOBAL_SCOPE); 63127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } 632394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->set_start_position(0); 633394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->set_end_position(source->length()); 634355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 635cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org // Compute the parsing mode. 636e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; 637e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (allow_natives_syntax() || 638e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org extension_ != NULL || 639e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org scope->is_eval_scope()) { 640cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org mode = PARSE_EAGERLY; 641cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org } 642cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org ParsingModeScope parsing_mode(this, mode); 643cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org 644f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Enters 'scope'. 645e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FunctionState function_state(this, scope, isolate()); 646f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 6471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org top_scope_->SetLanguageMode(info->language_mode()); 6487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 64943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool ok = true; 6500ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org int beg_loc = scanner().location().beg_pos; 65133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); 6521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (ok && !top_scope_->is_classic_mode()) { 6530ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); 6540ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 6551805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 6561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (ok && is_extended_mode()) { 6572c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org CheckConflictingVarDeclarations(top_scope_, &ok); 6581805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 6591805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 6609faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { 6619faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (body->length() != 1 || 6629faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org !body->at(0)->IsExpressionStatement() || 6639faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org !body->at(0)->AsExpressionStatement()-> 6649faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org expression()->IsFunctionLiteral()) { 665f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ReportMessage("single_function_literal", Vector<const char*>::empty()); 6669faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org ok = false; 6679faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 6689faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 6699faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org 67043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (ok) { 671b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewFunctionLiteral( 672911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org no_name, 673911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org top_scope_, 674fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org body, 675c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org function_state.materialized_literal_count(), 676c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org function_state.expected_property_count(), 67704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org function_state.handler_count(), 678911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 0, 67956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org FunctionLiteral::kNoDuplicateParameters, 6807c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org FunctionLiteral::ANONYMOUS_EXPRESSION, 681471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FunctionLiteral::kGlobalOrEval, 682f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org FunctionLiteral::kNotParenthesized, 683f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org FunctionLiteral::kNotGenerator); 684b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result->set_ast_properties(factory()->visitor()->ast_properties()); 685a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (stack_overflow_) { 686ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()->StackOverflow(); 68743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 68843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 68943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 69043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure the target stack is empty. 69143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(target_stack_ == NULL); 69243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 69343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 69443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 696f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 6975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgFunctionLiteral* Parser::ParseLazy() { 6987979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org HistogramTimerScope timer(isolate()->counters()->parse_lazy()); 699f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org Handle<String> source(String::cast(script_->source())); 7007979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org isolate()->counters()->total_parse_size()->Increment(source->length()); 701304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org int64_t start = FLAG_trace_parse ? OS::Ticks() : 0; 7025a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared_info = info()->shared_info(); 703304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 7045f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Initialize parser state. 7055f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org source->TryFlatten(); 706304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FunctionLiteral* result; 7075f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org if (source->IsExternalTwoByteString()) { 708154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ExternalTwoByteStringUtf16CharacterStream stream( 7095f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Handle<ExternalTwoByteString>::cast(source), 7104d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org shared_info->start_position(), 7114d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org shared_info->end_position()); 7121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org result = ParseLazy(&stream); 7135f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else { 714154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org GenericStringUtf16CharacterStream stream(source, 715154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org shared_info->start_position(), 716154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org shared_info->end_position()); 7171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org result = ParseLazy(&stream); 7185f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 719304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 720304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (FLAG_trace_parse && result != NULL) { 721304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org double ms = static_cast<double>(OS::Ticks() - start) / 1000; 722de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); 723304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org PrintF("[parsing function: %s - took %0.3f ms]\n", *name_chars, ms); 724304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 725304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org return result; 7265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 7275f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 7285f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 7291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgFunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { 7305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared_info = info()->shared_info(); 7319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org scanner_.Initialize(source); 732394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(top_scope_ == NULL); 7335f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org ASSERT(target_stack_ == NULL); 7345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 7354d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org Handle<String> name(String::cast(shared_info->name())); 7367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); 73765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->PushEnclosingName(name); 73865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 739471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 74043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 74143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Place holder for the result. 74243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FunctionLiteral* result = NULL; 74343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 74443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen { 74543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse the function literal. 746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 7475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org info()->SetGlobalScope(scope); 7485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (!info()->closure().is_null()) { 7495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, 7507028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org zone()); 7514d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } 752e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FunctionState function_state(this, scope, isolate()); 7535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); 7541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(scope->language_mode() != EXTENDED_MODE || 7555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org info()->is_extended_mode()); 7565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(info()->language_mode() == shared_info->language_mode()); 7571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org scope->SetLanguageMode(shared_info->language_mode()); 758dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org FunctionLiteral::FunctionType function_type = shared_info->is_expression() 7597c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org ? (shared_info->is_anonymous() 7607c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org ? FunctionLiteral::ANONYMOUS_EXPRESSION 7617c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org : FunctionLiteral::NAMED_EXPRESSION) 7627c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org : FunctionLiteral::DECLARATION; 76343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool ok = true; 76483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org result = ParseFunctionLiteral(name, 7657c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org false, // Strict mode name already checked. 766f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org shared_info->is_generator(), 7677c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org RelocInfo::kNoPosition, 768dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org function_type, 7697c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org &ok); 77043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure the results agree. 77143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(ok == (result != NULL)); 77243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 77343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 77443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure the target stack is empty. 77543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(target_stack_ == NULL); 77643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 77743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (result == NULL) { 778ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (stack_overflow_) isolate()->StackOverflow(); 779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 7804d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org Handle<String> inferred_name(shared_info->inferred_name()); 781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org result->set_inferred_name(inferred_name); 78243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 78343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 78443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 78543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 786f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 787bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.orgHandle<String> Parser::GetSymbol() { 788d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com int symbol_id = -1; 789e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (pre_parse_data() != NULL) { 790e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org symbol_id = pre_parse_data()->GetSymbolIdentifier(); 7915b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org } 7929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return LookupSymbol(symbol_id); 7935b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org} 7945b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 7955b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 796dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgvoid Parser::ReportMessage(const char* message, Vector<const char*> args) { 7975f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Scanner::Location source_location = scanner().location(); 798dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org ReportMessageAt(source_location, message, args); 799fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org} 800fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org 801fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org 802dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgvoid Parser::ReportMessage(const char* message, Vector<Handle<String> > args) { 803bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Scanner::Location source_location = scanner().location(); 804dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org ReportMessageAt(source_location, message, args); 805bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com} 806bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 807bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 808fa943b736b1d996084393011529d568165bb5d83lrn@chromium.orgvoid Parser::ReportMessageAt(Scanner::Location source_location, 809dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org const char* message, 810fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org Vector<const char*> args) { 81143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen MessageLocation location(script_, 812c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org source_location.beg_pos, 813c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org source_location.end_pos); 814ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Factory* factory = isolate()->factory(); 815ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<FixedArray> elements = factory->NewFixedArray(args.length()); 81643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < args.length(); i++) { 817ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); 8188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org elements->set(i, *arg_string); 81943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 820ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<JSArray> array = factory->NewJSArrayWithElements(elements); 821dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<Object> result = factory->NewSyntaxError(message, array); 822ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()->Throw(*result, &location); 82343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 82443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 82543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 826c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid Parser::ReportMessageAt(Scanner::Location source_location, 827dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org const char* message, 828c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Vector<Handle<String> > args) { 829c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org MessageLocation location(script_, 830c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org source_location.beg_pos, 831c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org source_location.end_pos); 832ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Factory* factory = isolate()->factory(); 833ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<FixedArray> elements = factory->NewFixedArray(args.length()); 834c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0; i < args.length(); i++) { 8358f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org elements->set(i, *args[i]); 836c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 837ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<JSArray> array = factory->NewJSArrayWithElements(elements); 838dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<Object> result = factory->NewSyntaxError(message, array); 839ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()->Throw(*result, &location); 840c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 841c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 842c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 843fa943b736b1d996084393011529d568165bb5d83lrn@chromium.orgvoid* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 84443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int end_token, 8452c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org bool is_eval, 84633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org bool is_global, 84743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* ok) { 84843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // SourceElements :: 849f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // (ModuleElement)* <end_token> 85043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 85143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Allocate a target stack to use for this set of source 85243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // elements. This way, all scripts and functions get their own 85343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // target stack thus avoiding illegal breaks and continues across 85443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // functions. 855e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org TargetScope scope(&this->target_stack_); 85643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 85743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(processor != NULL); 8580a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org bool directive_prologue = true; // Parsing directive prologue. 8590a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 86043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != end_token) { 8610a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (directive_prologue && peek() != Token::STRING) { 8620a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; 8630a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 8640a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 8650a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Scanner::Location token_loc = scanner().peek_location(); 86633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Statement* stat; 86733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (is_global && !is_eval) { 86833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org stat = ParseModuleElement(NULL, CHECK_OK); 86933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } else { 87033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org stat = ParseBlockElement(NULL, CHECK_OK); 87133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 8720a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (stat == NULL || stat->IsEmpty()) { 8730a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; // End of directive prologue. 8740a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org continue; 8750a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 8760a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 8770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (directive_prologue) { 8780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // A shot at a directive. 879f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ExpressionStatement* e_stat; 880f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Literal* literal; 8810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Still processing directive prologue? 8820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if ((e_stat = stat->AsExpressionStatement()) != NULL && 8830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org (literal = e_stat->expression()->AsLiteral()) != NULL && 8841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org literal->value()->IsString()) { 8851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> directive = Handle<String>::cast(literal->value()); 8860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 8870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Check "use strict" directive (ES5 14.1). 8881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (top_scope_->is_classic_mode() && 8894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org directive->Equals(isolate()->heap()->use_strict_string()) && 8900a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org token_loc.end_pos - token_loc.beg_pos == 8914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->heap()->use_strict_string()->length() + 2) { 8922c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // TODO(mstarzinger): Global strict eval calls, need their own scope 8932c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // as specified in ES5 10.4.2(3). The correct fix would be to always 8942c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // add this scope in DoParseProgram(), but that requires adaptations 8952c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // all over the code base, so we go with a quick-fix for now. 896cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org // In the same manner, we have to patch the parsing mode. 8972c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (is_eval && !top_scope_->is_eval_scope()) { 8982c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org ASSERT(top_scope_->is_global_scope()); 8992c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Scope* scope = NewScope(top_scope_, EVAL_SCOPE); 9002c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org scope->set_start_position(top_scope_->start_position()); 9012c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org scope->set_end_position(top_scope_->end_position()); 9022c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org top_scope_ = scope; 903cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org mode_ = PARSE_EAGERLY; 9042c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } 9051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // TODO(ES6): Fix entering extended mode, once it is specified. 906e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org top_scope_->SetLanguageMode(allow_harmony_scoping() 9071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ? EXTENDED_MODE : STRICT_MODE); 9080a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // "use strict" is the only directive for now. 9090a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; 9100a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 9110a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 9120a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // End of the directive prologue. 9130a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org directive_prologue = false; 9140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 9150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 9160a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 9177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org processor->Add(stat, zone()); 91843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 919911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 92043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; 92143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 92243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 92343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 924f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgStatement* Parser::ParseModuleElement(ZoneStringList* labels, 925f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org bool* ok) { 926f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // (Ecma 262 5th Edition, clause 14): 927f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // SourceElement: 928f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Statement 929f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // FunctionDeclaration 930f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // 931f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // In harmony mode we allow additionally the following productions 932f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModuleElement: 933f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // LetDeclaration 934f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ConstDeclaration 935f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModuleDeclaration 936f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ImportDeclaration 937f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ExportDeclaration 938f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // GeneratorDeclaration 939f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 940f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org switch (peek()) { 941f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::FUNCTION: 942812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseFunctionDeclaration(NULL, ok); 943f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::LET: 944f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::CONST: 945812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseVariableStatement(kModuleElement, NULL, ok); 946f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::IMPORT: 947f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseImportDeclaration(ok); 948f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::EXPORT: 949f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseExportDeclaration(ok); 950a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org default: { 951a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org Statement* stmt = ParseStatement(labels, CHECK_OK); 952a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org // Handle 'module' as a context-sensitive keyword. 953a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org if (FLAG_harmony_modules && 954a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org peek() == Token::IDENTIFIER && 955a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org !scanner().HasAnyLineTerminatorBeforeNext() && 956a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org stmt != NULL) { 957a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org ExpressionStatement* estmt = stmt->AsExpressionStatement(); 958a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org if (estmt != NULL && 959a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org estmt->expression()->AsVariableProxy() != NULL && 960a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org estmt->expression()->AsVariableProxy()->name()->Equals( 9614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->heap()->module_string()) && 962a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org !scanner().literal_contains_escapes()) { 963812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseModuleDeclaration(NULL, ok); 964a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 965a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 966a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org return stmt; 967a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 968f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 969f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 970f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 971f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 97281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.orgStatement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { 973f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModuleDeclaration: 974f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // 'module' Identifier Module 975f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 976f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Handle<String> name = ParseIdentifier(CHECK_OK); 977bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 978bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 979bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 980bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Module %s...\n", name->ToAsciiArray()); 981bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 982bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 983812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* module = ParseModule(CHECK_OK); 9848e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); 985812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 986812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org factory()->NewModuleDeclaration(proxy, module, top_scope_); 987812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 988812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 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 993bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 994bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("module %s : ", name->ToAsciiArray()); 995bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com module->interface()->Print(); 996bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 997bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 998bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 9997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (names) names->Add(name, zone()); 100081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org if (module->body() == NULL) 100181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org return factory()->NewEmptyStatement(); 100281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org else 10038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org return factory()->NewModuleStatement(proxy, module->body()); 1004f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1005f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1006f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1007f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModule(bool* ok) { 1008f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Module: 1009f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // '{' ModuleElement '}' 1010812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // '=' ModulePath ';' 1011812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'at' String ';' 1012f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1013f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org switch (peek()) { 1014f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::LBRACE: 1015f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseModuleLiteral(ok); 1016f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1017812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::ASSIGN: { 1018f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::ASSIGN, CHECK_OK); 1019812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* result = ParseModulePath(CHECK_OK); 1020812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1021812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return result; 1022812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1023f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1024812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org default: { 10251fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ExpectContextualKeyword(CStrVector("at"), CHECK_OK); 1026812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* result = ParseModuleUrl(CHECK_OK); 1027812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1028812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return result; 1029812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1030f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1031f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1032f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1033f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1034f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleLiteral(bool* ok) { 1035f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Module: 1036f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // '{' ModuleElement '}' 1037f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1038f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Construct block expecting 16 statements. 10395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Block* body = factory()->NewBlock(NULL, 16, false); 1040bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1041bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) PrintF("# Literal "); 1042bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1043f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Scope* scope = NewScope(top_scope_, MODULE_SCOPE); 1044f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1045f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::LBRACE, CHECK_OK); 1046f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org scope->set_start_position(scanner().location().beg_pos); 1047f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org scope->SetLanguageMode(EXTENDED_MODE); 1048f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1049f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org { 1050f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org BlockState block_state(this, scope); 10517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector collector(zone()); 1052f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Target target(&this->target_stack_, &collector); 1053f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Target target_body(&this->target_stack_, body); 1054f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1055f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org while (peek() != Token::RBRACE) { 1056f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Statement* stat = ParseModuleElement(NULL, CHECK_OK); 1057f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (stat && !stat->IsEmpty()) { 1058400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body->AddStatement(stat, zone()); 1059f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1060f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1061f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1062f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1063f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::RBRACE, CHECK_OK); 1064f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org scope->set_end_position(scanner().location().end_pos); 1065ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com body->set_scope(scope); 1066bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 106781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // Check that all exports are bound. 1068ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Interface* interface = scope->interface(); 106981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org for (Interface::Iterator it = interface->iterator(); 107081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org !it.done(); it.Advance()) { 107181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org if (scope->LocalLookup(it.name()) == NULL) { 107281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org Handle<String> name(it.name()); 107381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org ReportMessage("module_export_undefined", 107481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org Vector<Handle<String> >(&name, 1)); 107581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org *ok = false; 107681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org return NULL; 107781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org } 107881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org } 107981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org 1080ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com interface->MakeModule(ok); 108181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org ASSERT(*ok); 1082ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com interface->Freeze(ok); 108381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org ASSERT(*ok); 1084ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com return factory()->NewModuleLiteral(body, interface); 1085f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1086f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1087f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1088f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModulePath(bool* ok) { 1089f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModulePath: 1090f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Identifier 1091f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModulePath '.' Identifier 1092f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1093f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Module* result = ParseModuleVariable(CHECK_OK); 1094f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org while (Check(Token::PERIOD)) { 1095f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Handle<String> name = ParseIdentifierName(CHECK_OK); 1096bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1097bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 1098bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Path .%s ", name->ToAsciiArray()); 1099bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1100bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Module* member = factory()->NewModulePath(result, name); 11017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org result->interface()->Add(name, member->interface(), zone(), ok); 1102bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (!*ok) { 1103bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1104bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 1105bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); 1106bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("result: "); 1107bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com result->interface()->Print(); 1108bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("member: "); 1109bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com member->interface()->Print(); 1110bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1111bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1112bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); 1113bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com return NULL; 1114bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1115bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com result = member; 1116f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1117f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1118f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return result; 1119f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1120f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1121f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1122f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleVariable(bool* ok) { 1123f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ModulePath: 1124f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Identifier 1125f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1126f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Handle<String> name = ParseIdentifier(CHECK_OK); 1127bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1128bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 1129bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Module variable %s ", name->ToAsciiArray()); 1130bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1131f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org VariableProxy* proxy = top_scope_->NewUnresolved( 113228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org factory(), name, Interface::NewModule(zone()), 113328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org scanner().location().beg_pos); 1134bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1135f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return factory()->NewModuleVariable(proxy); 1136f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1137f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1138f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1139f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleUrl(bool* ok) { 1140f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Module: 1141812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // String 1142f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1143f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Expect(Token::STRING, CHECK_OK); 1144bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org Handle<String> symbol = GetSymbol(); 1145f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1146bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // TODO(ES6): Request JS resource from environment... 1147bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1148bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1149bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) PrintF("# Url "); 1150bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1151ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 11528e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Create an empty literal as long as the feature isn't finished. 11538e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org USE(symbol); 11548e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Scope* scope = NewScope(top_scope_, MODULE_SCOPE); 11558e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Block* body = factory()->NewBlock(NULL, 1, false); 11568e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org body->set_scope(scope); 11578e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Interface* interface = scope->interface(); 11588e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Module* result = factory()->NewModuleLiteral(body, interface); 1159ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com interface->Freeze(ok); 116081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org ASSERT(*ok); 116181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org interface->Unify(scope->interface(), zone(), ok); 116281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org ASSERT(*ok); 1163ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com return result; 1164f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1165f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1166f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1167812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgModule* Parser::ParseModuleSpecifier(bool* ok) { 1168812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ModuleSpecifier: 1169812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // String 1170812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ModulePath 1171812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1172812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org if (peek() == Token::STRING) { 1173812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseModuleUrl(ok); 1174812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } else { 1175812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseModulePath(ok); 1176812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1177812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 1178812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1179812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1180f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgBlock* Parser::ParseImportDeclaration(bool* ok) { 1181812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ImportDeclaration: 1182812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' 1183812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 1184812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // TODO(ES6): implement destructuring ImportSpecifiers 1185812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1186812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Expect(Token::IMPORT, CHECK_OK); 11877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneStringList names(1, zone()); 1188812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1189812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Handle<String> name = ParseIdentifierName(CHECK_OK); 11907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1191812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org while (peek() == Token::COMMA) { 1192812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Consume(Token::COMMA); 1193812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org name = ParseIdentifierName(CHECK_OK); 11947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1195812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1196812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 11971fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ExpectContextualKeyword(CStrVector("from"), CHECK_OK); 1198812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Module* module = ParseModuleSpecifier(CHECK_OK); 1199812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1200812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1201812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Generate a separate declaration for each identifier. 1202812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // TODO(ES6): once we implement destructuring, make that one declaration. 12035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Block* block = factory()->NewBlock(NULL, 1, true); 1204812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org for (int i = 0; i < names.length(); ++i) { 1205bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1206bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 1207bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Import %s ", names[i]->ToAsciiArray()); 1208bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 12097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Interface* interface = Interface::NewUnknown(zone()); 12107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org module->interface()->Add(names[i], interface, zone(), ok); 1211bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (!*ok) { 1212bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1213bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 1214bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); 1215bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("module: "); 1216bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com module->interface()->Print(); 1217bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1218bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1219bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); 1220bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com return NULL; 1221bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1222bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com VariableProxy* proxy = NewUnresolved(names[i], LET, interface); 1223812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1224812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org factory()->NewImportDeclaration(proxy, module, top_scope_); 1225812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 1226812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1227812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1228812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return block; 1229f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1230f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1231f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1232812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgStatement* Parser::ParseExportDeclaration(bool* ok) { 1233812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // ExportDeclaration: 1234812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' Identifier (',' Identifier)* ';' 1235812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' VariableDeclaration 1236812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' FunctionDeclaration 1237f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // 'export' GeneratorDeclaration 1238812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 'export' ModuleDeclaration 1239812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // 1240812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // TODO(ES6): implement structuring ExportSpecifiers 1241812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1242812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Expect(Token::EXPORT, CHECK_OK); 1243812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1244812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Statement* result = NULL; 12457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneStringList names(1, zone()); 1246812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org switch (peek()) { 1247812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::IDENTIFIER: { 1248812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Handle<String> name = ParseIdentifier(CHECK_OK); 1249812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Handle 'module' as a context-sensitive keyword. 125059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { 12517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1252812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org while (peek() == Token::COMMA) { 1253812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Consume(Token::COMMA); 1254812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org name = ParseIdentifier(CHECK_OK); 12557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org names.Add(name, zone()); 1256812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1257812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExpectSemicolon(CHECK_OK); 1258812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org result = factory()->NewEmptyStatement(); 1259812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } else { 1260812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org result = ParseModuleDeclaration(&names, CHECK_OK); 1261812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1262812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 1263812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1264812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1265812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::FUNCTION: 1266812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org result = ParseFunctionDeclaration(&names, CHECK_OK); 1267812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 1268812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1269812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::VAR: 1270812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::LET: 1271812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case Token::CONST: 1272812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); 1273812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 1274812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1275812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org default: 1276812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org *ok = false; 1277812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ReportUnexpectedToken(scanner().current_token()); 1278812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return NULL; 1279812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1280812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1281bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Extract declared names into export declarations and interface. 1282bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Interface* interface = top_scope_->interface(); 1283812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org for (int i = 0; i < names.length(); ++i) { 1284bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1285bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 1286bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Export %s ", names[i]->ToAsciiArray()); 1287bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 12887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Interface* inner = Interface::NewUnknown(zone()); 12897028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org interface->Add(names[i], inner, zone(), CHECK_OK); 12907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (!*ok) 12917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org return NULL; 1292bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com VariableProxy* proxy = NewUnresolved(names[i], LET, inner); 1293bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com USE(proxy); 1294bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // TODO(rossberg): Rethink whether we actually need to store export 1295bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // declarations (for compilation?). 1296bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // ExportDeclaration* declaration = 1297bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // factory()->NewExportDeclaration(proxy, top_scope_); 1298bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // top_scope_->AddDeclaration(declaration); 1299812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 1300812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1301812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ASSERT(result != NULL); 1302812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return result; 1303f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1304f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1305f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1306f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgStatement* Parser::ParseBlockElement(ZoneStringList* labels, 1307f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org bool* ok) { 1308f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // (Ecma 262 5th Edition, clause 14): 1309f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // SourceElement: 1310f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Statement 1311f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // FunctionDeclaration 1312f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // 1313f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // In harmony mode we allow additionally the following productions 1314f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // BlockElement (aka SourceElement): 1315f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // LetDeclaration 1316f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // ConstDeclaration 1317f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // GeneratorDeclaration 1318f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1319f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org switch (peek()) { 1320f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::FUNCTION: 1321812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseFunctionDeclaration(NULL, ok); 1322f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::LET: 1323f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org case Token::CONST: 1324812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return ParseVariableStatement(kModuleElement, NULL, ok); 1325f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org default: 1326f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ParseStatement(labels, ok); 1327f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 1328f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 1329f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1330f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 133143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { 133243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Statement :: 133343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Block 133443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableStatement 133543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // EmptyStatement 133643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ExpressionStatement 133743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IfStatement 133843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IterationStatement 133943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ContinueStatement 134043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // BreakStatement 134143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ReturnStatement 134243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WithStatement 134343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LabelledStatement 134443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // SwitchStatement 134543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ThrowStatement 134643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TryStatement 134743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // DebuggerStatement 134843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 134943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note: Since labels can only be used by 'break' and 'continue' 135043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // statements, which themselves are only valid within blocks, 135143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // iterations or 'switch' statements (i.e., BreakableStatements), 135243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // labels can be simply ignored in all other cases; except for 13533291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // trivial labeled break statements 'label: break label' which is 135443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parsed into an empty statement. 135543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 135643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Keep the source position of the statement 135743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int statement_pos = scanner().peek_location().beg_pos; 135843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* stmt = NULL; 135943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (peek()) { 136043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LBRACE: 136143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return ParseBlock(labels, ok); 136243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 136343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::CONST: // fall through 13641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org case Token::LET: 136543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::VAR: 1366812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org stmt = ParseVariableStatement(kStatement, NULL, ok); 136743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 136843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 136943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SEMICOLON: 137043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 1371b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewEmptyStatement(); 137243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 137343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::IF: 137443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stmt = ParseIfStatement(labels, ok); 137543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 137643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 137743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::DO: 13789d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com stmt = ParseDoWhileStatement(labels, ok); 137943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 138043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 138143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::WHILE: 138243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stmt = ParseWhileStatement(labels, ok); 138343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 138443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 138543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::FOR: 138643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stmt = ParseForStatement(labels, ok); 138743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 138843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 138943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::CONTINUE: 139043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stmt = ParseContinueStatement(ok); 139143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 139243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 139343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::BREAK: 139443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stmt = ParseBreakStatement(labels, ok); 139543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 139643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 139743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::RETURN: 139843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stmt = ParseReturnStatement(ok); 139943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 140043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 140143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::WITH: 140243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stmt = ParseWithStatement(labels, ok); 140343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 140443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 140543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SWITCH: 140643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stmt = ParseSwitchStatement(labels, ok); 140743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 140843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 140943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::THROW: 141043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stmt = ParseThrowStatement(ok); 141143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 141243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 141343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::TRY: { 141443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // NOTE: It is somewhat complicated to have labels on 141543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // try-statements. When breaking out of a try-finally statement, 141643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // one must take great care not to treat it as a 141743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // fall-through. It is much easier just to wrap the entire 141843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // try-statement in a statement block and put the labels there 14195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Block* result = factory()->NewBlock(labels, 1, false); 1420e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, result); 142143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TryStatement* statement = ParseTryStatement(CHECK_OK); 142237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (statement) { 142337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com statement->set_statement_pos(statement_pos); 142437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 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: 145143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stmt = ParseDebuggerStatement(ok); 145243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 145343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 145443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 145543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stmt = ParseExpressionOrLabelledStatement(labels, ok); 145643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 145743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 145843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Store the source position of the statement 145943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (stmt != NULL) stmt->set_statement_pos(statement_pos); 146043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return stmt; 146143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 146243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 146343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1464bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comVariableProxy* Parser::NewUnresolved( 1465bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Handle<String> name, VariableMode mode, Interface* interface) { 1466b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // If we are inside a function, a declaration of a var/const variable is a 1467b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // truly local variable, and the scope of the variable is always the function 1468b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // scope. 1469394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Let/const variables in harmony mode are always added to the immediately 1470394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // enclosing scope. 1471812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org return DeclarationScope(mode)->NewUnresolved( 147228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org factory(), name, interface, scanner().location().beg_pos); 1473812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 1474812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1475812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1476812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { 1477bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com VariableProxy* proxy = declaration->proxy(); 1478bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Handle<String> name = proxy->name(); 1479812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org VariableMode mode = declaration->mode(); 1480812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Scope* declaration_scope = DeclarationScope(mode); 1481812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Variable* var = NULL; 148243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 148381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // If a suitable scope exists, then we can statically declare this 148443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // variable and also set its mode. In any case, a Declaration node 148543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will be added to the scope so that the declaration can be added 148643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to the corresponding activation frame at runtime if necessary. 148743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // For instance declarations inside an eval scope need to be added 148843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to the calling function context. 14898e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org // Similarly, strict mode eval scope does not leak variable declarations to 14908e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org // the caller's scope so we declare all locals, too. 14914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (declaration_scope->is_function_scope() || 14921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org declaration_scope->is_strict_or_extended_eval_scope() || 1493f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org declaration_scope->is_block_scope() || 1494bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com declaration_scope->is_module_scope() || 1495355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org declaration_scope->is_global_scope()) { 149681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // Declare the variable in the declaration scope. 1497355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // For the global scope, we have to check for collisions with earlier 1498355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // (i.e., enclosing) global scopes, to maintain the illusion of a single 1499355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // global scope. 1500355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org var = declaration_scope->is_global_scope() 1501355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org ? declaration_scope->Lookup(name) 1502355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org : declaration_scope->LocalLookup(name); 150343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (var == NULL) { 150443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Declare the name. 1505812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org var = declaration_scope->DeclareLocal( 1506bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com name, mode, declaration->initialization(), proxy->interface()); 1507355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org } else if ((mode != VAR || var->mode() != VAR) && 1508355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org (!declaration_scope->is_global_scope() || 1509355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org IsLexicalVariableMode(mode) || 1510355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org IsLexicalVariableMode(var->mode()))) { 15111805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // The name was declared in this scope before; check for conflicting 15121805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // re-declarations. We have a conflict if either of the declarations is 1513355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // not a var (in the global scope, we also have to ignore legacy const for 1514355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // compatibility). There is similar code in runtime.cc in the Declare 15151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // functions. The function CheckNonConflictingScope checks for conflicting 15161805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // var and let bindings from different scopes whereas this is a check for 15171805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // conflicting declarations within the same scope. This check also covers 1518355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // the special case 15191805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // 15201805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // function () { let x; { var x; } } 15211805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // 15221805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // because the var declaration is hoisted to the function scope where 'x' 15231805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // is already bound. 1524355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org ASSERT(IsDeclaredVariableMode(var->mode())); 1525355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org if (is_extended_mode()) { 1526355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // In harmony mode we treat re-declarations as early errors. See 1527355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // ES5 16 for a definition of early errors. 1528355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); 1529355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org const char* elms[2] = { "Variable", *c_string }; 1530355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Vector<const char*> args(elms, 2); 1531355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org ReportMessage("redeclaration", args); 1532355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org *ok = false; 1533355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org return; 153443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1535dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message_string = 15368e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org isolate()->factory()->NewStringFromUtf8(CStrVector("Variable"), 15378e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org TENURED); 1538355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Expression* expression = 15394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org NewThrowTypeError(isolate()->factory()->redeclaration_string(), 1540dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org message_string, name); 1541355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org declaration_scope->SetIllegalRedeclaration(expression); 154243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 154343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 154443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 154543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We add a declaration node for every declaration. The compiler 154643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will only generate code if necessary. In particular, declarations 154743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // for inner local variables that do not represent functions won't 154843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // result in any generated code. 154943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 155043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that we always add an unresolved proxy even if it's not 155143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // used, simply because we don't know in this method (w/o extra 155243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parameters) if the proxy is needed or not. The proxy will be 155343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // bound during variable resolution time unless it was pre-bound 155443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // below. 155543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 155643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WARNING: This will lead to multiple declaration nodes for the 155743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // same variable if it is declared several times. This is not a 155843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // semantic issue as long as we keep the source order, but it may be 155943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // a performance issue since it may lead to repeated 156043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Runtime::DeclareContextSlot() calls. 1561812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org declaration_scope->AddDeclaration(declaration); 156243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1563355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org if (mode == CONST && declaration_scope->is_global_scope()) { 156427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // For global const variables we bind the proxy to a variable. 156543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(resolve); // should be set by all callers 15663e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org Variable::Kind kind = Variable::NORMAL; 156710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org var = new(zone()) Variable( 156810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org declaration_scope, name, mode, true, kind, 156910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org kNeedsInitialization, proxy->interface()); 157027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } else if (declaration_scope->is_eval_scope() && 15711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org declaration_scope->is_classic_mode()) { 157227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // For variable declarations in a non-strict eval scope the proxy is bound 157327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // to a lookup variable to force a dynamic declaration using the 157427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // DeclareContextSlot runtime function. 157527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Variable::Kind kind = Variable::NORMAL; 157610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org var = new(zone()) Variable( 157710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org declaration_scope, name, mode, true, kind, 157810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org declaration->initialization(), proxy->interface()); 157927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org var->AllocateTo(Variable::LOOKUP, -1); 158027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org resolve = true; 158143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 158243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 158343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If requested and we have a local variable, bind the proxy to the variable 158443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // at parse-time. This is used for functions (and consts) declared inside 158543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // statements: the corresponding function (or const) variable must be in the 158643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function scope and not a statement-local scope, e.g. as provided with a 158743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'with' statement: 158843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 158943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // with (obj) { 159043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function f() {} 159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // } 159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // which is translated into: 159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 159543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // with (obj) { 159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // // in this case this is not: 'var f; f = function () {};' 159743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // var f = function () {}; 159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // } 159943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 160043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that if 'f' is accessed from inside the 'with' statement, it 160143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will be allocated in the context (because we must be able to look 160243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // it up dynamically) but it will also be accessed statically, i.e., 160343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // with a context slot index and a context chain length for this 160443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // initialization code. Thus, inside the 'with' statement, we need 160543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // both access to the static and the dynamic context chain; the 160643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // runtime needs to provide both. 1607bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (resolve && var != NULL) { 1608bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com proxy->BindTo(var); 1609bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 1610bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_harmony_modules) { 1611bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com bool ok; 1612bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1613bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 1614bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Declare %s\n", var->name()->ToAsciiArray()); 1615bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 16167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org proxy->interface()->Unify(var->interface(), zone(), &ok); 1617bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (!ok) { 1618bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 1619bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interfaces) { 1620bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("DECLARE TYPE ERROR\n"); 1621bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("proxy: "); 1622bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com proxy->interface()->Print(); 1623bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("var: "); 1624bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com var->interface()->Print(); 1625bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1626bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 1627bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1)); 1628bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1629bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 1630bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com } 163143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 163243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 163343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 163443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Language extension which is only enabled for source files loaded 163543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// through the API's extension mechanism. A native function 163643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// declaration is resolved by looking up the function through a 163743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// callback provided by the extension. 163843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseNativeDeclaration(bool* ok) { 163943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::FUNCTION, CHECK_OK); 164043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> name = ParseIdentifier(CHECK_OK); 164143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 164243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool done = (peek() == Token::RPAREN); 164343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!done) { 164443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ParseIdentifier(CHECK_OK); 164543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen done = (peek() == Token::RPAREN); 1646fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (!done) { 1647fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org Expect(Token::COMMA, CHECK_OK); 1648fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org } 164943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 165043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 165143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SEMICOLON, CHECK_OK); 165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure that the function containing the native declaration 165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // isn't lazily compiled. The extension structures are only 165543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // accessible while parsing the first time not when reparsing 165643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // because of lazy compilation. 1657812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org DeclarationScope(VAR)->ForceEagerCompilation(); 165843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute the function template for the native function. 166043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen v8::Handle<v8::FunctionTemplate> fun_template = 166143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen extension_->GetNativeFunction(v8::Utils::ToLocal(name)); 166243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(!fun_template.IsEmpty()); 166343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1664c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Instantiate the function and create a shared function info from it. 166543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction()); 166643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const int literals = fun->NumberOfLiterals(); 166743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Code> code = Handle<Code>(fun->shared()->code()); 1668b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); 1669b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org bool is_generator = false; 1670b5737496145078e47f3d28f19ed8d918e2254738ager@chromium.org Handle<SharedFunctionInfo> shared = 1671b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org isolate()->factory()->NewSharedFunctionInfo(name, literals, is_generator, 1672b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org code, Handle<ScopeInfo>(fun->shared()->scope_info())); 16735d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org shared->set_construct_stub(*construct_stub); 167443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1675c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Copy the function data to the shared function info. 16765d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org shared->set_function_data(fun->shared()->function_data()); 1677b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org int parameters = fun->shared()->formal_parameter_count(); 16785d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org shared->set_formal_parameter_count(parameters); 167943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 168043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1240846): It's weird that native function declarations are 168143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // introduced dynamically when we meet their declarations, whereas 1682f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // other functions are set up when entering the surrounding scope. 168328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); 1684812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1685812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org factory()->NewVariableDeclaration(proxy, VAR, top_scope_); 1686812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 1687c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org SharedFunctionInfoLiteral* lit = 1688b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewSharedFunctionInfoLiteral(shared); 1689b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewExpressionStatement( 1690b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewAssignment( 1691812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); 169243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 169343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 169443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1695812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgStatement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { 1696c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // FunctionDeclaration :: 1697c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 1698f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // GeneratorDeclaration :: 1699f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // 'function' '*' Identifier '(' FormalParameterListopt ')' 1700f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // '{' FunctionBody '}' 170143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::FUNCTION, CHECK_OK); 170243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int function_token_position = scanner().location().beg_pos; 1703e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool is_generator = allow_generators() && Check(Token::MUL); 170404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool is_strict_reserved = false; 170504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org Handle<String> name = ParseIdentifierOrStrictReservedWord( 170604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org &is_strict_reserved, CHECK_OK); 1707c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org FunctionLiteral* fun = ParseFunctionLiteral(name, 170804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org is_strict_reserved, 1709f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org is_generator, 1710c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org function_token_position, 17117c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org FunctionLiteral::DECLARATION, 1712c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org CHECK_OK); 1713c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Even if we're not at the top-level of the global or a function 1714355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // scope, we treat it as such and introduce the function with its 1715c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // initial value upon entering the corresponding scope. 1716355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // In extended mode, a function behaves as a lexical binding, except in the 1717355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // global scope. 1718355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org VariableMode mode = 1719355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; 172028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); 1721812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1722812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_); 1723812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, true, CHECK_OK); 17247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (names) names->Add(name, zone()); 1725b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewEmptyStatement(); 172643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 172743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 172843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 172943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenBlock* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { 17301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); 17314acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 173243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Block :: 173343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '{' Statement* '}' 173443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 173543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that a Block does not introduce a new execution scope! 173643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // (ECMA-262, 3rd, 12.2) 173743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 173843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Construct block expecting 16 statements. 17395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Block* result = factory()->NewBlock(labels, 16, false); 1740e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, result); 174143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 174243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::RBRACE) { 174343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* stat = ParseStatement(NULL, CHECK_OK); 17446db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (stat && !stat->IsEmpty()) { 1745400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(stat, zone()); 17466db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 174743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 174843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACE, CHECK_OK); 174943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 175043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 175143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 175243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17534acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.orgBlock* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { 1754f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // The harmony mode uses block elements instead of statements. 1755c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // 1756c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Block :: 1757f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // '{' BlockElement* '}' 1758c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 17594acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Construct block expecting 16 statements. 17605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Block* body = factory()->NewBlock(labels, 16, false); 1761394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); 17624acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 17634acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Parse the statements and collect escaping labels. 17644acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Expect(Token::LBRACE, CHECK_OK); 1765394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com block_scope->set_start_position(scanner().location().beg_pos); 1766c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org { BlockState block_state(this, block_scope); 17677028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector collector(zone()); 1768394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Target target(&this->target_stack_, &collector); 17694acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Target target_body(&this->target_stack_, body); 17704acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 17714acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org while (peek() != Token::RBRACE) { 1772f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Statement* stat = ParseBlockElement(NULL, CHECK_OK); 17734acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (stat && !stat->IsEmpty()) { 1774400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body->AddStatement(stat, zone()); 17754acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 17764acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 17774acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 17784acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Expect(Token::RBRACE, CHECK_OK); 1779394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com block_scope->set_end_position(scanner().location().end_pos); 17801805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org block_scope = block_scope->FinalizeBlockScope(); 1781ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com body->set_scope(block_scope); 1782486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return body; 17834acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org} 17844acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 17854acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 1786b645116853c677aca8a316381b87441ba6004f67danno@chromium.orgBlock* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 1787812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ZoneStringList* names, 1788b645116853c677aca8a316381b87441ba6004f67danno@chromium.org bool* ok) { 178943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableStatement :: 179043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableDeclarations ';' 179143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Handle<String> ignore; 1793f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Block* result = 1794812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); 179543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 179643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 179743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 179843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1799ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1800ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgbool Parser::IsEvalOrArguments(Handle<String> string) { 18014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return string.is_identical_to(isolate()->factory()->eval_string()) || 18024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org string.is_identical_to(isolate()->factory()->arguments_string()); 18030a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 180443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1805ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 180643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// If the variable declaration declares exactly one non-const 180778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// variable, then *out is set to that variable. In all other cases, 180878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// *out is untouched; in particular, it is the caller's responsibility 180943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to initialize it properly. This mechanism is used for the parsing 181043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// of 'for-in' loops. 1811394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comBlock* Parser::ParseVariableDeclarations( 1812394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com VariableDeclarationContext var_context, 1813394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com VariableDeclarationProperties* decl_props, 1814812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ZoneStringList* names, 1815394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<String>* out, 1816394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool* ok) { 181743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VariableDeclarations :: 1818394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] 1819394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 1820394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // The ES6 Draft Rev3 specifies the following grammar for const declarations 1821394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 1822394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ConstDeclaration :: 1823394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // const ConstBinding (',' ConstBinding)* ';' 1824394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ConstBinding :: 1825394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Identifier '=' AssignmentExpression 1826394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 1827394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // TODO(ES6): 1828394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ConstBinding :: 1829394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // BindingPattern '=' AssignmentExpression 1830b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org VariableMode mode = VAR; 183180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // True if the binding needs initialization. 'let' and 'const' declared 183280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // bindings are created uninitialized by their declaration nodes and 183380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // need initialization. 'var' declared bindings are always initialized 183480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // immediately by their declaration nodes. 183580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org bool needs_init = false; 183643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool is_const = false; 183780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Token::Value init_op = Token::INIT_VAR; 183843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::VAR) { 183943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::VAR); 184043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (peek() == Token::CONST) { 18411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: 18421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 18431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 18441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 18451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // * It is a Syntax Error if the code that matches this production is not 18461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // contained in extended code. 18471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 18481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // However disallowing const in classic mode will break compatibility with 18491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // existing pages. Therefore we keep allowing const with the old 18501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // non-harmony semantics in classic mode. 185143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::CONST); 18521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org switch (top_scope_->language_mode()) { 18531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org case CLASSIC_MODE: 18541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org mode = CONST; 18551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org init_op = Token::INIT_CONST; 18561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org break; 18571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org case STRICT_MODE: 18581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ReportMessage("strict_const", Vector<const char*>::empty()); 1859394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com *ok = false; 1860394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return NULL; 18611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org case EXTENDED_MODE: 1862f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (var_context == kStatement) { 18631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // In extended mode 'const' declarations are only allowed in source 18641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // element positions. 18651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ReportMessage("unprotected_const", Vector<const char*>::empty()); 18661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org *ok = false; 18671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return NULL; 18681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 18691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org mode = CONST_HARMONY; 18701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org init_op = Token::INIT_CONST_HARMONY; 18719ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 187243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen is_const = true; 187380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org needs_init = true; 1874b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } else if (peek() == Token::LET) { 18751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // ES6 Draft Rev4 section 12.2.1: 18761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 18771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // LetDeclaration : let LetBindingList ; 18781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // 18791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // * It is a Syntax Error if the code that matches this production is not 18801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // contained in extended code. 18811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!is_extended_mode()) { 18821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ReportMessage("illegal_let", Vector<const char*>::empty()); 18831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org *ok = false; 18841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return NULL; 18851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 1886b645116853c677aca8a316381b87441ba6004f67danno@chromium.org Consume(Token::LET); 1887f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (var_context == kStatement) { 1888394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Let declarations are only allowed in source element positions. 1889b645116853c677aca8a316381b87441ba6004f67danno@chromium.org ReportMessage("unprotected_let", Vector<const char*>::empty()); 1890b645116853c677aca8a316381b87441ba6004f67danno@chromium.org *ok = false; 1891b645116853c677aca8a316381b87441ba6004f67danno@chromium.org return NULL; 1892b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } 1893b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org mode = LET; 189480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org needs_init = true; 189580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org init_op = Token::INIT_LET; 189643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 189743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); // by current callers 189843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 189943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1900812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Scope* declaration_scope = DeclarationScope(mode); 1901812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1902b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // The scope of a var/const declared variable anywhere inside a function 190343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1904b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // transform a source-level var/const declaration into a (Function) 190543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Scope declaration, and rewrite the source-level initialization into an 190643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // assignment statement. We use a block to collect multiple assignments. 190743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 190843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We mark the block as initializer block because we don't want the 190943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // rewriter to add a '.result' assignment to such a block (to get compliant 191043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // behavior for code such as print(eval('var x = 7')), and for cosmetic 191143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // reasons when pretty-printing. Also, unless an assignment (initialization) 191243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is inside an initializer block, it is ignored. 191343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 191443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create new block with one expected declaration. 19155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Block* block = factory()->NewBlock(NULL, 1, true); 191643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int nvars = 0; // the number of variables declared 19174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Handle<String> name; 191843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen do { 191965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Enter(); 192065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 192143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse variable name. 192243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (nvars > 0) Consume(Token::COMMA); 19234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org name = ParseIdentifier(CHECK_OK); 192465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushVariableName(name); 192543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19260a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Strict mode variables may not be named eval or arguments 19271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) { 19280a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org ReportMessage("strict_var_name", Vector<const char*>::empty()); 19290a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org *ok = false; 19300a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return NULL; 19310a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 19320a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 193343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Declare variable. 193443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Note that we *always* must treat the initial value via a separate init 193543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // assignment for variables and constants because the value must be assigned 193643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // when the variable is encountered in the source. But the variable/constant 193743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is declared (and set to 'undefined') upon entering the function within 193843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // which the variable or constant is declared. Only function variables have 193943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // an initial value in the declaration (because they are initialized upon 194043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // entering the function). 194143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 194243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we have a const declaration, in an inner scope, the proxy is always 194343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // bound to the declared variable (independent of possibly surrounding with 194443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // statements). 1945394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // For let/const declarations in harmony mode, we can also immediately 1946394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // pre-resolve the proxy because it resides in the same scope as the 1947394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // declaration. 194828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org Interface* interface = 194928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org is_const ? Interface::NewConst() : Interface::NewValue(); 195028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org VariableProxy* proxy = NewUnresolved(name, mode, interface); 1951812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declaration* declaration = 1952812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org factory()->NewVariableDeclaration(proxy, mode, top_scope_); 1953812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Declare(declaration, mode != VAR, CHECK_OK); 195443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen nvars++; 19554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { 19567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ReportMessageAt(scanner().location(), "too_many_variables", 19577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Vector<const char*>::empty()); 19587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org *ok = false; 19597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return NULL; 19607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 19617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (names) names->Add(name, zone()); 196243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 196343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse initialization expression if present and/or needed. A 196443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration of the form: 196543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 196643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // var v = x; 196743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 196843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is syntactic sugar for: 196943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 197043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // var v; v = x; 197143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 19724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // In particular, we need to re-lookup 'v' (in top_scope_, not 19734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // declaration_scope) as it may be a different 'v' than the 'v' in the 19744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // declaration (e.g., if we are inside a 'with' statement or 'catch' 19754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // block). 197643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 197743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // However, note that const declarations are different! A const 197843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration of the form: 197943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 198043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // const c = x; 198143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 198243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is *not* syntactic sugar for: 198343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 198443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // const c; c = x; 198543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 198643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The "variable" c initialized to x is the same as the declared 198743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // one - there is no re-lookup (see the last parameter of the 198843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Declare() call above). 198943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Scope* initialization_scope = is_const ? declaration_scope : top_scope_; 199143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* value = NULL; 199243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int position = -1; 1993394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Harmony consts have non-optional initializers. 1994394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { 199543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::ASSIGN, CHECK_OK); 199643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen position = scanner().location().beg_pos; 1997b645116853c677aca8a316381b87441ba6004f67danno@chromium.org value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 199865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Don't infer if it is "a = function(){...}();"-like expression. 199904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (fni_ != NULL && 200004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org value->AsCall() == NULL && 200104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org value->AsCallNew() == NULL) { 200204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org fni_->Infer(); 2003c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2004c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fni_->RemoveLastFunction(); 200504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 2006394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (decl_props != NULL) *decl_props = kHasInitializers; 200743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 200843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2009c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Record the end position of the initializer. 2010c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org if (proxy->var() != NULL) { 2011c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org proxy->var()->set_initializer_position(scanner().location().end_pos); 2012c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org } 2013c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 201480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Make sure that 'const x' and 'let x' initialize 'x' to undefined. 201580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org if (value == NULL && needs_init) { 201643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen value = GetLiteralUndefined(); 201743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 201843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 201943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Global variable declarations must be compiled in a specific 202043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // way. When the script containing the global variable declaration 202143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is entered, the global variable must be declared, so that if it 2022ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // doesn't exist (on the global object itself, see ES5 errata) it 202343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // gets created with an initial undefined value. This is handled 202443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // by the declarations part of the function representing the 202543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // top-level global code; see Runtime::DeclareGlobalVariable. If 202643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // it already exists (in the object or in a prototype), it is 202743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // *not* touched until the variable declaration statement is 202843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // executed. 202943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 203043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Executing the variable declaration statement will always 203143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // guarantee to give the global object a "local" variable; a 203243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // variable defined in the global object and not in any 203343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // prototype. This way, global variable declarations can shadow 203443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // properties in the prototype chain, but only after the variable 203543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration statement has been executed. This is important in 203643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // browsers where the global object (window) has lots of 203743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // properties defined in prototype objects. 2038355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org if (initialization_scope->is_global_scope() && 2039355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org !IsLexicalVariableMode(mode)) { 204043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute the arguments for the runtime call. 20417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Expression*>* arguments = 20427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<Expression*>(3, zone()); 2043c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // We have at least 1 parameter. 20447028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org arguments->Add(factory()->NewLiteral(name), zone()); 204543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CallRuntime* initialize; 20469ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 204743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (is_const) { 20487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org arguments->Add(value, zone()); 20499ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org value = NULL; // zap the value to avoid the unnecessary assignment 20509ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 20519ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Construct the call to Runtime_InitializeConstGlobal 20529ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // and add it to the initialization statement block. 20539ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Note that the function does different things depending on 20549ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // the number of arguments (1 or 2). 2055b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org initialize = factory()->NewCallRuntime( 20564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->InitializeConstGlobal_string(), 2057b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org Runtime::FunctionForId(Runtime::kInitializeConstGlobal), 2058b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org arguments); 205943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 20609ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Add strict mode. 20619ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // We may want to pass singleton to avoid Literal allocations. 20621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org LanguageMode language_mode = initialization_scope->language_mode(); 20637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org arguments->Add(factory()->NewNumberLiteral(language_mode), zone()); 20649ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 20659ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Be careful not to assign a value to the global variable if 20669ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // we're in a with. The initialization value should not 20679ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // necessarily be stored in the global object in that case, 20689ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // which is why we need to generate a separate assignment node. 20699ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org if (value != NULL && !inside_with()) { 20707028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org arguments->Add(value, zone()); 20719ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org value = NULL; // zap the value to avoid the unnecessary assignment 20729ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 20739ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 20749ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Construct the call to Runtime_InitializeVarGlobal 20759ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // and add it to the initialization statement block. 20769ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Note that the function does different things depending on 20779ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // the number of arguments (2 or 3). 2078b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org initialize = factory()->NewCallRuntime( 20794a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->InitializeVarGlobal_string(), 2080b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org Runtime::FunctionForId(Runtime::kInitializeVarGlobal), 2081b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org arguments); 208243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 20839ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 2084400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org block->AddStatement(factory()->NewExpressionStatement(initialize), 2085400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org zone()); 208627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } else if (needs_init) { 208727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // Constant initializations always assign to the declared constant which 208827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // is always at the function scope level. This is only relevant for 208927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // dynamically looked-up variables and constants (the start context for 209027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // constant lookups is always the function context, while it is the top 209127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // context for var declared variables). Sigh... 209227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // For 'let' and 'const' declared variables in harmony mode the 209327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // initialization also always assigns to the declared variable. 209427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(proxy != NULL); 209527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(proxy->var() != NULL); 209627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(value != NULL); 209727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Assignment* assignment = 2098b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewAssignment(init_op, proxy, value, position); 2099400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org block->AddStatement(factory()->NewExpressionStatement(assignment), 2100400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org zone()); 210127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org value = NULL; 210243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 210343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2104486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Add an assignment node to the initialization statement block if we still 210527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // have a pending initialization value. 210643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (value != NULL) { 210727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(mode == VAR); 210827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // 'var' initializations are simply assignments (with all the consequences 210927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // if they are inside a 'with' statement - they may change a 'with' object 211027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // property). 2111b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org VariableProxy* proxy = 211228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org initialization_scope->NewUnresolved(factory(), name, interface); 2113c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Assignment* assignment = 2114b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewAssignment(init_op, proxy, value, position); 2115400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org block->AddStatement(factory()->NewExpressionStatement(assignment), 2116400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org zone()); 211743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 211865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 211965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Leave(); 212043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } while (peek() == Token::COMMA); 212143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // If there was a single non-const declaration, return it in the output 21234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // parameter for possible use by for/in. 21244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (nvars == 1 && !is_const) { 21254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org *out = name; 212643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 212743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 212843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return block; 212943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 213043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 213143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 213243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { 213343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(!label.is_null()); 213443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (labels != NULL) 213543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = labels->length(); i-- > 0; ) 213643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (labels->at(i).is_identical_to(label)) 213743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 213843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 213943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 214043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 214143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 214243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 214343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, 214443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* ok) { 214543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ExpressionStatement | LabelledStatement :: 214643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expression ';' 214743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Identifier ':' Statement 214883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org bool starts_with_idenfifier = peek_any_identifier(); 214943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expr = ParseExpression(true, CHECK_OK); 21507b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && 215143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen expr->AsVariableProxy() != NULL && 215243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen !expr->AsVariableProxy()->is_this()) { 21534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Expression is a single identifier, and not, e.g., a parenthesized 21544a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // identifier. 215543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen VariableProxy* var = expr->AsVariableProxy(); 215643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> label = var->name(); 215743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1240780): We don't check for redeclaration of labels 215843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // during preparsing since keeping track of the set of active 215943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // labels requires nontrivial changes to the way scopes are 216043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // structured. However, these are probably changes we want to 216143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // make later anyway so we should go back and fix this then. 2162fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { 216383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS); 2164fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org const char* elms[2] = { "Label", *c_string }; 2165fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org Vector<const char*> args(elms, 2); 2166fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org ReportMessage("redeclaration", args); 2167fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org *ok = false; 2168fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org return NULL; 216943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 21707028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (labels == NULL) { 21717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org labels = new(zone()) ZoneStringList(4, zone()); 21727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 21737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org labels->Add(label, zone()); 2174fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // Remove the "ghost" variable that turned out to be a label 2175fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // from the top scope. This way, we don't try to resolve it 2176fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // during the scope processing. 2177fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org top_scope_->RemoveUnresolved(var); 217843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COLON, CHECK_OK); 217943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return ParseStatement(labels, ok); 218043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 218143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21827b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // If we have an extension, we allow a native function declaration. 21837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // A native function declaration starts with "native function" with 21847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // no line-terminator between the two words. 21857b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (extension_ != NULL && 21867b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org peek() == Token::FUNCTION && 2187df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org !scanner().HasAnyLineTerminatorBeforeNext() && 21887b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org expr != NULL && 21897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org expr->AsVariableProxy() != NULL && 21907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org expr->AsVariableProxy()->name()->Equals( 21914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->heap()->native_string()) && 21927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org !scanner().literal_contains_escapes()) { 21937b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org return ParseNativeDeclaration(ok); 21947b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 21957b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 2196a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org // Parsed expression statement, or the context-sensitive 'module' keyword. 2197a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org // Only expect semicolon in the former case. 2198a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org if (!FLAG_harmony_modules || 2199a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org peek() != Token::IDENTIFIER || 2200a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org scanner().HasAnyLineTerminatorBeforeNext() || 2201a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org expr->AsVariableProxy() == NULL || 2202a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org !expr->AsVariableProxy()->name()->Equals( 22034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->heap()->module_string()) || 2204a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org scanner().literal_contains_escapes()) { 2205a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org ExpectSemicolon(CHECK_OK); 2206a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 2207b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewExpressionStatement(expr); 220843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 220943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 221043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 221143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenIfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { 221243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IfStatement :: 221343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'if' '(' Expression ')' Statement ('else' Statement)? 221443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 221543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::IF, CHECK_OK); 221643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 221743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* condition = ParseExpression(true, CHECK_OK); 221843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 221943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* then_statement = ParseStatement(labels, CHECK_OK); 222043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* else_statement = NULL; 222143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::ELSE) { 222243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 222343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen else_statement = ParseStatement(labels, CHECK_OK); 2224fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org } else { 2225b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org else_statement = factory()->NewEmptyStatement(); 222643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2227b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewIfStatement(condition, then_statement, else_statement); 222843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 222943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 223043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 223143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseContinueStatement(bool* ok) { 223243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ContinueStatement :: 223343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'continue' Identifier? ';' 223443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 223543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::CONTINUE, CHECK_OK); 223668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org Handle<String> label = Handle<String>::null(); 223743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value tok = peek(); 2238df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org if (!scanner().HasAnyLineTerminatorBeforeNext() && 22399258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 224043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen label = ParseIdentifier(CHECK_OK); 224143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 224243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IterationStatement* target = NULL; 2243fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org target = LookupContinueTarget(label, CHECK_OK); 2244fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (target == NULL) { 2245c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Illegal continue statement. 2246c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org const char* message = "illegal_continue"; 2247c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Vector<Handle<String> > args; 2248c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (!label.is_null()) { 2249c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org message = "unknown_label"; 2250c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org args = Vector<Handle<String> >(&label, 1); 2251c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 2252c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ReportMessageAt(scanner().location(), message, args); 2253c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org *ok = false; 2254c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return NULL; 225543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 225643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 2257b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewContinueStatement(target); 225843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 225943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 226043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 226143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { 226243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // BreakStatement :: 226343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'break' Identifier? ';' 226443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 226543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::BREAK, CHECK_OK); 226643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> label; 226743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value tok = peek(); 2268df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org if (!scanner().HasAnyLineTerminatorBeforeNext() && 22699258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 227043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen label = ParseIdentifier(CHECK_OK); 227143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 22723291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Parse labeled break statements that target themselves into 227343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // empty statements, e.g. 'l1: l2: l3: break l2;' 227443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!label.is_null() && ContainsLabel(labels, label)) { 2275b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org ExpectSemicolon(CHECK_OK); 2276b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewEmptyStatement(); 227743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 227843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakableStatement* target = NULL; 2279fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org target = LookupBreakTarget(label, CHECK_OK); 2280fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (target == NULL) { 2281c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Illegal break statement. 2282c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org const char* message = "illegal_break"; 2283c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Vector<Handle<String> > args; 2284c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (!label.is_null()) { 2285c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org message = "unknown_label"; 2286c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org args = Vector<Handle<String> >(&label, 1); 2287c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 2288c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ReportMessageAt(scanner().location(), message, args); 2289c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org *ok = false; 2290c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return NULL; 229143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 229243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 2293b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewBreakStatement(target); 229443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 229543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 229643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 229743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseReturnStatement(bool* ok) { 229843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ReturnStatement :: 229943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'return' Expression? ';' 230043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 230143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Consume the return token. It is necessary to do the before 230243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // reporting any errors on it, because of the way errors are 230343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // reported (underlining). 230443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RETURN, CHECK_OK); 230543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 230664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Token::Value tok = peek(); 230764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Statement* result; 230877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Expression* return_value; 230964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (scanner().HasAnyLineTerminatorBeforeNext() || 231064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org tok == Token::SEMICOLON || 231164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org tok == Token::RBRACE || 231264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org tok == Token::EOS) { 231377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org return_value = GetLiteralUndefined(); 231464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 231577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org return_value = ParseExpression(true, CHECK_OK); 231677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 231777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org ExpectSemicolon(CHECK_OK); 231877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (is_generator()) { 231977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Expression* generator = factory()->NewVariableProxy( 232077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org current_function_state_->generator_object_variable()); 232177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Expression* yield = factory()->NewYield( 232277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org generator, return_value, Yield::FINAL, RelocInfo::kNoPosition); 232377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org result = factory()->NewExpressionStatement(yield); 232477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 232577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org result = factory()->NewReturnStatement(return_value); 232664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 232764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 232843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // An ECMAScript program is considered syntactically incorrect if it 232943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // contains a return statement that is not within the body of a 233043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function. See ECMA-262, section 12.9, page 67. 233143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 233243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // To be consistent with KJS we report the syntax error at runtime. 23334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Scope* declaration_scope = top_scope_->DeclarationScope(); 23344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (declaration_scope->is_global_scope() || 23354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org declaration_scope->is_eval_scope()) { 2336dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message = isolate()->factory()->illegal_return_string(); 2337dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Expression* throw_error = 2338dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org NewThrowSyntaxError(message, Handle<Object>::null()); 2339b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewExpressionStatement(throw_error); 234043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 234164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org return result; 234243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 234343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 234443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 234543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { 234643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WithStatement :: 234743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'with' '(' Expression ')' Statement 234843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 234943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::WITH, CHECK_OK); 23500a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 23511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode()) { 23520a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org ReportMessage("strict_mode_with", Vector<const char*>::empty()); 23530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org *ok = false; 23540a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return NULL; 23550a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 23560a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 235743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 235843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expr = ParseExpression(true, CHECK_OK); 235943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 236043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23614acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org top_scope_->DeclarationScope()->RecordWithStatement(); 2362394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); 2363394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Statement* stmt; 2364c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org { BlockState block_state(this, with_scope); 2365394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com with_scope->set_start_position(scanner().peek_location().beg_pos); 2366394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com stmt = ParseStatement(labels, CHECK_OK); 2367394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com with_scope->set_end_position(scanner().location().end_pos); 2368394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 2369ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org return factory()->NewWithStatement(with_scope, expr, stmt); 237043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 237143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 237243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 237343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenCaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { 237443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // CaseClause :: 237543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'case' Expression ':' Statement* 237643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'default' ':' Statement* 237743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 237843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* label = NULL; // NULL expression indicates default case 237943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::CASE) { 238043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::CASE, CHECK_OK); 238143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen label = ParseExpression(true, CHECK_OK); 238243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 238343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::DEFAULT, CHECK_OK); 238443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (*default_seen_ptr) { 238543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReportMessage("multiple_defaults_in_switch", 238643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Vector<const char*>::empty()); 238743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 238843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 238943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 239043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *default_seen_ptr = true; 239143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 239243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COLON, CHECK_OK); 2393a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int pos = scanner().location().beg_pos; 23947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Statement*>* statements = 23957028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<Statement*>(5, zone()); 239643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::CASE && 239743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen peek() != Token::DEFAULT && 239843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen peek() != Token::RBRACE) { 239943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* stat = ParseStatement(NULL, CHECK_OK); 24007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org statements->Add(stat, zone()); 240143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 240243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2403717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org return new(zone()) CaseClause(isolate(), label, statements, pos); 240443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 240543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 240643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 240743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenSwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, 240843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* ok) { 240943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // SwitchStatement :: 241043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'switch' '(' Expression ')' '{' CaseClause* '}' 241143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2412b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org SwitchStatement* statement = factory()->NewSwitchStatement(labels); 2413e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, statement); 241443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 241543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SWITCH, CHECK_OK); 241643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 241743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* tag = ParseExpression(true, CHECK_OK); 241843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 241943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 242043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool default_seen = false; 24217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone()); 242243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 242343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::RBRACE) { 242443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); 24257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org cases->Add(clause, zone()); 242643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 242743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACE, CHECK_OK); 242843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2429fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (statement) statement->Initialize(tag, cases); 243043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return statement; 243143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 243243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 243343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 243443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseThrowStatement(bool* ok) { 243543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ThrowStatement :: 243643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'throw' Expression ';' 243743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 243843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::THROW, CHECK_OK); 243943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int pos = scanner().location().beg_pos; 2440df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org if (scanner().HasAnyLineTerminatorBeforeNext()) { 244143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReportMessage("newline_after_throw", Vector<const char*>::empty()); 244243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 244343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 244443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 244543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* exception = ParseExpression(true, CHECK_OK); 244643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 244743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2448b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos)); 244943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 245043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 245143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 245243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTryStatement* Parser::ParseTryStatement(bool* ok) { 245343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TryStatement :: 245443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'try' Block Catch 245543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'try' Block Finally 245643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'try' Block Catch Finally 245743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 245843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Catch :: 245943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'catch' '(' Identifier ')' Block 246043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 246143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Finally :: 246243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'finally' Block 246343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 246443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::TRY, CHECK_OK); 246543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector try_collector(zone()); 246743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Block* try_block; 246843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24696d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org { Target target(&this->target_stack_, &try_collector); 247043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen try_block = ParseBlock(NULL, CHECK_OK); 247143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 247243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 247343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value tok = peek(); 247443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tok != Token::CATCH && tok != Token::FINALLY) { 247543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); 247643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 247743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 247843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 247943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 248043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we can break out from the catch block and there is a finally block, 24816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // then we will need to collect escaping targets from the catch 24826d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // block. Since we don't know yet if there will be a finally block, we 24836d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // always collect the targets. 24847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TargetCollector catch_collector(zone()); 24854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Scope* catch_scope = NULL; 24864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Variable* catch_variable = NULL; 24876d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Block* catch_block = NULL; 24886d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Handle<String> name; 248943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tok == Token::CATCH) { 249043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::CATCH); 249143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 249243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 2493394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com catch_scope = NewScope(top_scope_, CATCH_SCOPE); 2494394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com catch_scope->set_start_position(scanner().location().beg_pos); 24956d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org name = ParseIdentifier(CHECK_OK); 24960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 24971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) { 24980a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org ReportMessage("strict_catch_variable", Vector<const char*>::empty()); 24990a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org *ok = false; 25000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return NULL; 25010a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 25020a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 250343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 250443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 250543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::LBRACE) { 25064acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Target target(&this->target_stack_, &catch_collector); 25071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org VariableMode mode = is_extended_mode() ? LET : VAR; 2508c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org catch_variable = 2509c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org catch_scope->DeclareLocal(name, mode, kCreatedInitialized); 25104acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 2511c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org BlockState block_state(this, catch_scope); 251255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org catch_block = ParseBlock(NULL, CHECK_OK); 251343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 251443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 251543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2516394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com catch_scope->set_end_position(scanner().location().end_pos); 251743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tok = peek(); 251843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 251943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25206d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Block* finally_block = NULL; 25216d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org if (tok == Token::FINALLY || catch_block == NULL) { 252243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::FINALLY); 252343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen finally_block = ParseBlock(NULL, CHECK_OK); 252443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 252543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 252643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Simplify the AST nodes by converting: 25276d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // 'try B0 catch B1 finally B2' 252843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to: 25296d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // 'try { try B0 catch B1 } finally B2' 253043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2531fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (catch_block != NULL && finally_block != NULL) { 25324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // If we have both, create an inner try/catch. 25334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(catch_scope != NULL && catch_variable != NULL); 253404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int index = current_function_state_->NextHandlerIndex(); 2535b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org TryCatchStatement* statement = factory()->NewTryCatchStatement( 2536b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org index, try_block, catch_scope, catch_variable, catch_block); 25376d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org statement->set_escaping_targets(try_collector.targets()); 25385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org try_block = factory()->NewBlock(NULL, 1, false); 2539400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org try_block->AddStatement(statement, zone()); 25404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org catch_block = NULL; // Clear to indicate it's been handled. 254143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 254243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 254343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TryStatement* result = NULL; 2544fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org if (catch_block != NULL) { 2545fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org ASSERT(finally_block == NULL); 25464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(catch_scope != NULL && catch_variable != NULL); 254704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int index = current_function_state_->NextHandlerIndex(); 2548b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewTryCatchStatement( 2549b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org index, try_block, catch_scope, catch_variable, catch_block); 2550fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org } else { 2551fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org ASSERT(finally_block != NULL); 255204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int index = current_function_state_->NextHandlerIndex(); 2553b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewTryFinallyStatement(index, try_block, finally_block); 25546d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // Combine the jump targets of the try block and the possible catch block. 25557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org try_collector.targets()->AddAll(*catch_collector.targets(), zone()); 255643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 255743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25586d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org result->set_escaping_targets(try_collector.targets()); 255943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 256043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 256143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 256243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25639d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comDoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, 25649d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com bool* ok) { 256543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // DoStatement :: 256643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'do' Statement 'while' '(' Expression ')' ';' 256743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2568b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org DoWhileStatement* loop = factory()->NewDoWhileStatement(labels); 2569e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 257043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 257143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::DO, CHECK_OK); 257243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 257343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::WHILE, CHECK_OK); 257443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 2575c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2576c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org if (loop != NULL) { 2577c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org int position = scanner().location().beg_pos; 2578c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org loop->set_condition_position(position); 2579c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org } 2580c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 258143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* cond = ParseExpression(true, CHECK_OK); 258243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 258343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 258443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Allow do-statements to be terminated with and without 258543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // semi-colons. This allows code such as 'do;while(0)return' to 258643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parse, which would not be the case if we had used the 258743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ExpectSemicolon() functionality here. 258843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 258943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25909d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (loop != NULL) loop->Initialize(cond, body); 259143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return loop; 259243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 259343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 259443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25959d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comWhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { 259643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // WhileStatement :: 259743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'while' '(' Expression ')' Statement 259843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2599b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org WhileStatement* loop = factory()->NewWhileStatement(labels); 2600e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 260143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 260243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::WHILE, CHECK_OK); 260343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 260443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* cond = ParseExpression(true, CHECK_OK); 260543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 260643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 260743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26089d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (loop != NULL) loop->Initialize(cond, body); 260943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return loop; 261043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 261143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 261243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 261341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgbool Parser::CheckInOrOf(bool accept_OF, 261441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ForEachStatement::VisitMode* visit_mode) { 26151fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org if (Check(Token::IN)) { 26161fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org *visit_mode = ForEachStatement::ENUMERATE; 26171fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return true; 261841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } else if (allow_for_of() && accept_OF && 261941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org CheckContextualKeyword(CStrVector("of"))) { 26201fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org *visit_mode = ForEachStatement::ITERATE; 26211fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return true; 26221fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26231fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return false; 26241fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org} 26251fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26261fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26271fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid Parser::InitializeForEachStatement(ForEachStatement* stmt, 26281fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* each, 26291fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* subject, 26301fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Statement* body) { 26311fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForOfStatement* for_of = stmt->AsForOfStatement(); 26321fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26331fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org if (for_of != NULL) { 26341fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Factory* heap_factory = isolate()->factory(); 26351fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Handle<String> iterator_str = heap_factory->InternalizeOneByteString( 26361fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org STATIC_ASCII_VECTOR(".iterator")); 26371fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Handle<String> result_str = heap_factory->InternalizeOneByteString( 26381fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org STATIC_ASCII_VECTOR(".result")); 26391fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Variable* iterator = 26401fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org top_scope_->DeclarationScope()->NewTemporary(iterator_str); 26411fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Variable* result = top_scope_->DeclarationScope()->NewTemporary(result_str); 26421fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26431fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* assign_iterator; 26441fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* next_result; 26451fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_done; 26461fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* assign_each; 26471fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26481fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // var iterator = iterable; 26491fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org { 26501fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 26511fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org assign_iterator = factory()->NewAssignment( 26521fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); 26531fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26541fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26551fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // var result = iterator.next(); 26561fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org { 26571fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 26581fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* next_literal = 26591fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org factory()->NewLiteral(heap_factory->next_string()); 26601fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* next_property = factory()->NewProperty( 26611fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org iterator_proxy, next_literal, RelocInfo::kNoPosition); 26621fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ZoneList<Expression*>* next_arguments = 26631fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org new(zone()) ZoneList<Expression*>(0, zone()); 26641fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* next_call = factory()->NewCall( 26651fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org next_property, next_arguments, RelocInfo::kNoPosition); 26661fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_proxy = factory()->NewVariableProxy(result); 26671fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org next_result = factory()->NewAssignment( 26681fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); 26691fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26701fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26711fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // result.done 26721fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org { 26731fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* done_literal = 26741fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org factory()->NewLiteral(heap_factory->done_string()); 26751fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_proxy = factory()->NewVariableProxy(result); 26761fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org result_done = factory()->NewProperty( 26771fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org result_proxy, done_literal, RelocInfo::kNoPosition); 26781fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26791fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26801fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // each = result.value 26811fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org { 26821fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* value_literal = 26831fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org factory()->NewLiteral(heap_factory->value_string()); 26841fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_proxy = factory()->NewVariableProxy(result); 26851fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Expression* result_value = factory()->NewProperty( 26861fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org result_proxy, value_literal, RelocInfo::kNoPosition); 26871fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org assign_each = factory()->NewAssignment( 26881fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); 26891fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26901fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26911fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org for_of->Initialize(each, subject, body, 26921fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org assign_iterator, next_result, result_done, assign_each); 26931fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } else { 26941fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org stmt->Initialize(each, subject, body); 26951fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 26961fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org} 26971fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 26981fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 269943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { 270043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ForStatement :: 270143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 270243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 270343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* init = NULL; 270443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2705394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Create an in-between scope for let-bound iteration variables. 2706394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Scope* saved_scope = top_scope_; 2707394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); 2708394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com top_scope_ = for_scope; 2709394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 271043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::FOR, CHECK_OK); 271143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 2712394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope->set_start_position(scanner().location().beg_pos); 271343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::SEMICOLON) { 271443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::VAR || peek() == Token::CONST) { 271528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org bool is_const = peek() == Token::CONST; 27164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Handle<String> name; 271741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org VariableDeclarationProperties decl_props = kHasNoInitializers; 271843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Block* variable_statement = 271941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, 272041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org CHECK_OK); 272141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org bool accept_OF = decl_props == kHasNoInitializers; 27221fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement::VisitMode mode; 27234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 272441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { 272528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org Interface* interface = 272628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org is_const ? Interface::NewConst() : Interface::NewValue(); 27271fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); 2728e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 272943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 273043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* enumerable = ParseExpression(true, CHECK_OK); 273143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 273243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 273333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org VariableProxy* each = 273433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org top_scope_->NewUnresolved(factory(), name, interface); 273543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 27361fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org InitializeForEachStatement(loop, each, enumerable, body); 27375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Block* result = factory()->NewBlock(NULL, 2, false); 2738400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(variable_statement, zone()); 2739400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(loop, zone()); 2740394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com top_scope_ = saved_scope; 2741394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope->set_end_position(scanner().location().end_pos); 2742394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope = for_scope->FinalizeBlockScope(); 2743394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(for_scope == NULL); 2744fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org // Parsed for-in loop w/ variable/const declaration. 2745fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org return result; 274643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 274743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen init = variable_statement; 274843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2749394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else if (peek() == Token::LET) { 2750394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<String> name; 2751394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com VariableDeclarationProperties decl_props = kHasNoInitializers; 2752394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Block* variable_statement = 2753812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, 2754812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org CHECK_OK); 2755394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool accept_IN = !name.is_null() && decl_props != kHasInitializers; 275641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org bool accept_OF = decl_props == kHasNoInitializers; 27571fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement::VisitMode mode; 27581fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 275941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (accept_IN && CheckInOrOf(accept_OF, &mode)) { 2760394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Rewrite a for-in statement of the form 2761394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2762394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // for (let x in e) b 2763394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2764394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // into 2765394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2766394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // <let x' be a temporary variable> 2767394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // for (x' in e) { 2768394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // let x; 2769394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // x = x'; 2770394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // b; 2771394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // } 2772394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2773394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // TODO(keuchel): Move the temporary variable to the block scope, after 2774394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // implementing stack allocated block scoped variables. 277533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Factory* heap_factory = isolate()->factory(); 277633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Handle<String> tempstr = 27774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org heap_factory->NewConsString(heap_factory->dot_for_string(), name); 27784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<String> tempname = heap_factory->InternalizeString(tempstr); 277933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); 2780b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 27811fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); 2782394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Target target(&this->target_stack_, loop); 2783394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 278433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // The expression does not see the loop variable. 278533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org top_scope_ = saved_scope; 2786394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Expression* enumerable = ParseExpression(true, CHECK_OK); 278733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org top_scope_ = for_scope; 2788394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Expect(Token::RPAREN, CHECK_OK); 278943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 279033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org VariableProxy* each = 279133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); 2792394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Statement* body = ParseStatement(NULL, CHECK_OK); 27935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Block* body_block = factory()->NewBlock(NULL, 3, false); 2794b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org Assignment* assignment = factory()->NewAssignment( 2795b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); 2796394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Statement* assignment_statement = 2797b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewExpressionStatement(assignment); 2798400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body_block->AddStatement(variable_statement, zone()); 2799400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body_block->AddStatement(assignment_statement, zone()); 2800400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org body_block->AddStatement(body, zone()); 28011fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); 2802394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com top_scope_ = saved_scope; 2803394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope->set_end_position(scanner().location().end_pos); 2804394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope = for_scope->FinalizeBlockScope(); 2805ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com body_block->set_scope(for_scope); 2806394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Parsed for-in loop w/ let declaration. 2807394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return loop; 2808394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2809394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 2810394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com init = variable_statement; 2811394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 281243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 281343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expression = ParseExpression(false, CHECK_OK); 28141fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement::VisitMode mode; 281541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org bool accept_OF = expression->AsVariableProxy(); 28161fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 281741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (CheckInOrOf(accept_OF, &mode)) { 2818c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Signal a reference error if the expression is an invalid 2819c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // left-hand side expression. We could report this as a syntax 2820c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // error here but for compatibility with JSC we choose to report 2821c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // the error at runtime. 282243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (expression == NULL || !expression->IsValidLeftHandSide()) { 2823dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message = 28244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->invalid_lhs_in_for_in_string(); 2825dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org expression = NewThrowReferenceError(message); 282643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 28271fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); 2828e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 282943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 283043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* enumerable = ParseExpression(true, CHECK_OK); 283143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 283243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 283343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 28341fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org InitializeForEachStatement(loop, expression, enumerable, body); 2835394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com top_scope_ = saved_scope; 2836394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope->set_end_position(scanner().location().end_pos); 2837394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope = for_scope->FinalizeBlockScope(); 2838394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(for_scope == NULL); 283943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parsed for-in loop. 284043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return loop; 284143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 284243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 2843b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org init = factory()->NewExpressionStatement(expression); 284443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 284543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 284643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 284743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 284843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Standard 'for' loop 2849b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org ForStatement* loop = factory()->NewForStatement(labels); 2850e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Target target(&this->target_stack_, loop); 285143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 285243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parsed initializer at this point. 285343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SEMICOLON, CHECK_OK); 285443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 285543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* cond = NULL; 285643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::SEMICOLON) { 285743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cond = ParseExpression(true, CHECK_OK); 285843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 285943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SEMICOLON, CHECK_OK); 286043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 286143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* next = NULL; 286243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::RPAREN) { 286343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* exp = ParseExpression(true, CHECK_OK); 2864b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org next = factory()->NewExpressionStatement(exp); 286543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 286643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 286743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 286843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Statement* body = ParseStatement(NULL, CHECK_OK); 2869394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com top_scope_ = saved_scope; 2870394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope->set_end_position(scanner().location().end_pos); 2871394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for_scope = for_scope->FinalizeBlockScope(); 2872394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (for_scope != NULL) { 2873394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Rewrite a for statement of the form 2874394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2875394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // for (let x = i; c; n) b 2876394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2877394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // into 2878394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // 2879394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // { 2880394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // let x = i; 2881394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // for (; c; n) b 2882394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // } 2883394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(init != NULL); 28845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Block* result = factory()->NewBlock(NULL, 2, false); 2885400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(init, zone()); 2886400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org result->AddStatement(loop, zone()); 2887ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com result->set_scope(for_scope); 28881fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org loop->Initialize(NULL, cond, next, body); 2889394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return result; 2890394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 28911fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org loop->Initialize(init, cond, next, body); 2892394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return loop; 2893394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 289443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 289543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 289643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 289743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence = 1 289843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseExpression(bool accept_IN, bool* ok) { 289943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expression :: 290043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // AssignmentExpression 290143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expression ',' AssignmentExpression 290243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 290343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); 290443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() == Token::COMMA) { 290543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COMMA, CHECK_OK); 290665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org int position = scanner().location().beg_pos; 290743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 2908b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = 2909b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewBinaryOperation(Token::COMMA, result, right, position); 291043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 291143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 291243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 291343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 291443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 291543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence = 2 291643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { 291743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // AssignmentExpression :: 291843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ConditionalExpression 2919f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // YieldExpression 292043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LeftHandSideExpression AssignmentOperator AssignmentExpression 292143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2922f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (peek() == Token::YIELD && is_generator()) { 2923f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return ParseYieldExpression(ok); 2924f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } 2925f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 292665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Enter(); 292743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); 292843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 292943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!Token::IsAssignmentOp(peek())) { 293065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Leave(); 293143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parsed conditional expression only (no assignment). 293243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return expression; 293343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 293443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2935c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Signal a reference error if the expression is an invalid left-hand 2936c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // side expression. We could report this as a syntax error here but 2937c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // for compatibility with JSC we choose to report the error at 2938c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // runtime. 2939a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // TODO(ES5): Should change parsing for spec conformance. 294043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (expression == NULL || !expression->IsValidLeftHandSide()) { 2941dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message = 29424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->invalid_lhs_in_assignment_string(); 2943dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org expression = NewThrowReferenceError(message); 294443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 294543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode()) { 2947378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Assignment to eval or arguments is disallowed in strict mode. 2948378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); 2949378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 295064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MarkAsLValue(expression); 2951378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 295243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value op = Next(); // Get assignment operator. 295343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int pos = scanner().location().beg_pos; 295443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 295543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 295643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1231235): We try to estimate the set of properties set by 295743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // constructors. We define a new property whenever there is an 295843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // assignment to a property of 'this'. We should probably only add 295943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // properties if we haven't seen them before. Otherwise we'll 296043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // probably overestimate the number of properties. 296143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Property* property = expression ? expression->AsProperty() : NULL; 296243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (op == Token::ASSIGN && 296343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen property != NULL && 296443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen property->obj()->AsVariableProxy() != NULL && 296543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen property->obj()->AsVariableProxy()->is_this()) { 2966c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org current_function_state_->AddProperty(); 296743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 296843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 296921b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org // If we assign a function literal to a property we pretenure the 297021b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org // literal so it can be added as a constant function property. 297121b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org if (property != NULL && right->AsFunctionLiteral() != NULL) { 2972c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org right->AsFunctionLiteral()->set_pretenure(); 297321b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org } 297421b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org 297565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) { 297665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Check if the right hand side is a call to avoid inferring a 297765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // name if we're dealing with "a = function(){...}();"-like 297865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // expression. 297965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if ((op == Token::INIT_VAR 298065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org || op == Token::INIT_CONST 298165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org || op == Token::ASSIGN) 298204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org && (right->AsCall() == NULL && right->AsCallNew() == NULL)) { 298365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->Infer(); 2984c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2985c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fni_->RemoveLastFunction(); 298665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 298765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->Leave(); 298865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 298965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 2990b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewAssignment(op, expression, right, pos); 299143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 299243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 299343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2994f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgExpression* Parser::ParseYieldExpression(bool* ok) { 2995f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // YieldExpression :: 2996f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // 'yield' '*'? AssignmentExpression 2997f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org int position = scanner().peek_location().beg_pos; 2998f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Expect(Token::YIELD, CHECK_OK); 299977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Yield::Kind kind = 300077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; 3001e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Expression* generator_object = factory()->NewVariableProxy( 3002e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org current_function_state_->generator_object_variable()); 3003f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Expression* expression = ParseAssignmentExpression(false, CHECK_OK); 30044e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org Yield* yield = 30054e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org factory()->NewYield(generator_object, expression, kind, position); 30064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (kind == Yield::DELEGATING) { 30074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org yield->set_index(current_function_state_->NextHandlerIndex()); 30084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 30094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org return yield; 3010f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org} 3011f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 3012f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 301343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence = 3 301443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { 301543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ConditionalExpression :: 301643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LogicalOrExpression 301743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 301843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 301943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We start using the binary expression parser for prec >= 4 only! 302043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); 302143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::CONDITIONAL) return expression; 302243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::CONDITIONAL); 302343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // In parsing the first assignment expression in conditional 302443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // expressions we always accept the 'in' keyword; see ECMA-262, 302543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // section 11.12, page 58. 30262356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org int left_position = scanner().peek_location().beg_pos; 302743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* left = ParseAssignmentExpression(true, CHECK_OK); 302843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COLON, CHECK_OK); 30292356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org int right_position = scanner().peek_location().beg_pos; 303043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 3031b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewConditional( 3032b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org expression, left, right, left_position, right_position); 303343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 303443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 303543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 303643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic int Precedence(Token::Value tok, bool accept_IN) { 303743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tok == Token::IN && !accept_IN) 303843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; // 0 precedence will terminate binary expression parsing 303943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 304043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return Token::Precedence(tok); 304143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 304243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 304343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 304443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence >= 4 304543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { 304643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(prec >= 4); 304743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* x = ParseUnaryExpression(CHECK_OK); 304843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 304943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // prec1 >= 4 305043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (Precedence(peek(), accept_IN) == prec1) { 305143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value op = Next(); 305265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org int position = scanner().location().beg_pos; 305343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); 305443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 305543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute some expressions involving only number literals. 30561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() && 30571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { 30581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org double x_val = x->AsLiteral()->value()->Number(); 30591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org double y_val = y->AsLiteral()->value()->Number(); 306043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 306143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (op) { 306243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::ADD: 3063b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewNumberLiteral(x_val + y_val); 306443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 306543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SUB: 3066b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewNumberLiteral(x_val - y_val); 306743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 306843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::MUL: 3069b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewNumberLiteral(x_val * y_val); 307043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 307143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::DIV: 3072b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewNumberLiteral(x_val / y_val); 307343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 3074b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org case Token::BIT_OR: { 3075b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); 3076b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewNumberLiteral(value); 307743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 3078b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org } 3079b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org case Token::BIT_AND: { 3080b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); 3081b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewNumberLiteral(value); 308243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 3083b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org } 3084b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org case Token::BIT_XOR: { 3085b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); 3086b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewNumberLiteral(value); 308743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 3088b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org } 308943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SHL: { 309043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); 3091b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewNumberLiteral(value); 309243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 309343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 309443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SHR: { 309543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t shift = DoubleToInt32(y_val) & 0x1f; 309643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t value = DoubleToUint32(x_val) >> shift; 3097b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewNumberLiteral(value); 309843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 309943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 310043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::SAR: { 310143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t shift = DoubleToInt32(y_val) & 0x1f; 310243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); 3103b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewNumberLiteral(value); 310443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; 310543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 310643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 310743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 310843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 310943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 311043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 311143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // For now we distinguish between comparisons and other binary 311243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // operations. (We could combine the two and get rid of this 311365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // code and AST node eventually.) 311443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (Token::IsCompareOp(op)) { 311543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We have a comparison. 311643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value cmp = op; 311743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (op) { 311843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::NE: cmp = Token::EQ; break; 311943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; 312043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: break; 312143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3122b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewCompareOperation(cmp, x, y, position); 312343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (cmp != op) { 312443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The comparison was negated - add a NOT. 3125b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewUnaryOperation(Token::NOT, x, position); 312643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 312743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 312843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 312943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We have a "normal" binary operation. 3130b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org x = factory()->NewBinaryOperation(op, x, y, position); 313143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 313243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 313343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 313443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return x; 313543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 313643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 313743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 313843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseUnaryExpression(bool* ok) { 313943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // UnaryExpression :: 314043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // PostfixExpression 314143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'delete' UnaryExpression 314243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'void' UnaryExpression 314343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'typeof' UnaryExpression 314443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '++' UnaryExpression 314543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '--' UnaryExpression 314643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '+' UnaryExpression 314743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '-' UnaryExpression 314843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '~' UnaryExpression 314943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '!' UnaryExpression 315043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 315143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value op = peek(); 315243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (Token::IsUnaryOp(op)) { 315343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen op = Next(); 31548e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org int position = scanner().location().beg_pos; 3155c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Expression* expression = ParseUnaryExpression(CHECK_OK); 315643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31577b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (expression != NULL && (expression->AsLiteral() != NULL)) { 31581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Object> literal = expression->AsLiteral()->value(); 31597b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (op == Token::NOT) { 31607b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // Convert the literal to a boolean condition and negate it. 31619faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org bool condition = literal->BooleanValue(); 3162fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Handle<Object> result(isolate()->heap()->ToBoolean(!condition), 3163fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org isolate()); 3164b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewLiteral(result); 31657b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } else if (literal->IsNumber()) { 31667b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // Compute some expressions involving only number literals. 31677b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org double value = literal->Number(); 31687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org switch (op) { 31697b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org case Token::ADD: 31707b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org return expression; 31717b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org case Token::SUB: 3172b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewNumberLiteral(-value); 31737b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org case Token::BIT_NOT: 3174b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewNumberLiteral(~DoubleToInt32(value)); 31757b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org default: 31767b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org break; 31777b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 317843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 317943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 318043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 318149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // "delete identifier" is a syntax error in strict mode. 31821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (op == Token::DELETE && !top_scope_->is_classic_mode()) { 318349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org VariableProxy* operand = expression->AsVariableProxy(); 318449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (operand != NULL && !operand->is_this()) { 318549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org ReportMessage("strict_delete", Vector<const char*>::empty()); 318649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org *ok = false; 318749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org return NULL; 318849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 318949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 319049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 3191b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org // Desugar '+foo' into 'foo*1', this enables the collection of type feedback 3192b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org // without any special stub and the multiplication is removed later in 3193b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org // Crankshaft's canonicalization pass. 3194b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (op == Token::ADD) { 3195b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org return factory()->NewBinaryOperation(Token::MUL, 3196b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org expression, 3197b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org factory()->NewNumberLiteral(1), 3198b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org position); 3199b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 3200594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The same idea for '-foo' => 'foo*(-1)'. 3201594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (op == Token::SUB) { 3202594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return factory()->NewBinaryOperation(Token::MUL, 3203594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org expression, 3204594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org factory()->NewNumberLiteral(-1), 3205594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org position); 3206594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 3207594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // ...and one more time for '~foo' => 'foo^(~0)'. 3208594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (op == Token::BIT_NOT) { 3209594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return factory()->NewBinaryOperation(Token::BIT_XOR, 3210594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org expression, 3211594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org factory()->NewNumberLiteral(~0), 3212594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org position); 3213594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 3214b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 3215b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewUnaryOperation(op, expression, position); 321643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 321743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (Token::IsCountOp(op)) { 321843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen op = Next(); 3219c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Expression* expression = ParseUnaryExpression(CHECK_OK); 3220c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Signal a reference error if the expression is an invalid 3221c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // left-hand side expression. We could report this as a syntax 3222c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // error here but for compatibility with JSC we choose to report the 3223c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // error at runtime. 3224c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org if (expression == NULL || !expression->IsValidLeftHandSide()) { 3225dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message = 32264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->invalid_lhs_in_prefix_op_string(); 3227dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org expression = NewThrowReferenceError(message); 322843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3229378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 32301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode()) { 3231378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Prefix expression operand in strict mode may not be eval or arguments. 3232378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); 3233378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 323464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MarkAsLValue(expression); 3235378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 323665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org int position = scanner().location().beg_pos; 3237b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewCountOperation(op, 3238b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org true /* prefix */, 3239b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org expression, 3240b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org position); 324143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 324243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 324343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return ParsePostfixExpression(ok); 324443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 324543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 324643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 324743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 324843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParsePostfixExpression(bool* ok) { 324943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // PostfixExpression :: 325043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LeftHandSideExpression ('++' | '--')? 325143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3252c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Expression* expression = ParseLeftHandSideExpression(CHECK_OK); 3253df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org if (!scanner().HasAnyLineTerminatorBeforeNext() && 32545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Token::IsCountOp(peek())) { 3255c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Signal a reference error if the expression is an invalid 3256c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // left-hand side expression. We could report this as a syntax 3257c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // error here but for compatibility with JSC we choose to report the 3258c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // error at runtime. 3259c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org if (expression == NULL || !expression->IsValidLeftHandSide()) { 3260dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message = 32614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->invalid_lhs_in_postfix_op_string(); 3262dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org expression = NewThrowReferenceError(message); 326343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3264378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 32651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode()) { 3266378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Postfix expression operand in strict mode may not be eval or arguments. 3267378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); 3268378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 326964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MarkAsLValue(expression); 3270378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 327143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value next = Next(); 327265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org int position = scanner().location().beg_pos; 3273c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org expression = 3274b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewCountOperation(next, 3275b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org false /* postfix */, 3276b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org expression, 3277b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org position); 327843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3279c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org return expression; 328043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 328143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 328243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 328343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseLeftHandSideExpression(bool* ok) { 328443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LeftHandSideExpression :: 328543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // (NewExpression | MemberExpression) ... 328643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 328743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* result; 328843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::NEW) { 328943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseNewExpression(CHECK_OK); 329043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 329143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseMemberExpression(CHECK_OK); 329243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 329343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 329443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (true) { 329543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (peek()) { 329643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LBRACK: { 329743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::LBRACK); 329843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int pos = scanner().location().beg_pos; 329943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* index = ParseExpression(true, CHECK_OK); 3300b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewProperty(result, index, pos); 330143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACK, CHECK_OK); 330243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 330343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 330443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 330543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LPAREN: { 3306f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com int pos; 3307f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com if (scanner().current_token() == Token::IDENTIFIER) { 3308f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // For call of an identifier we want to report position of 3309f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // the identifier as position of the call in the stack trace. 3310f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com pos = scanner().location().beg_pos; 3311f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } else { 3312f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // For other kinds of calls we record position of the parenthesis as 3313f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // position of the call. Note that this is extremely important for 3314f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // expressions of the form function(){...}() for which call position 3315f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // should not point to the closing brace otherwise it will intersect 3316f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // with positions recorded for function literal and confuse debugger. 3317f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com pos = scanner().peek_location().beg_pos; 3318de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org // Also the trailing parenthesis are a hint that the function will 3319de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org // be called immediately. If we happen to have parsed a preceding 3320de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org // function literal eagerly, we can also compile it eagerly. 3321de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { 3322de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org result->AsFunctionLiteral()->set_parenthesized(); 3323de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org } 3324f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } 332543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 332643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 332743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Keep track of eval() calls since they disable all local variable 3328a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // optimizations. 3329a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // The calls that need special treatment are the 3330c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // direct eval calls. These calls are all of the form eval(...), with 3331c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // no explicit receiver. 3332c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // These calls are marked as potentially direct eval calls. Whether 3333c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // they are actually direct calls to eval is determined at run time. 3334fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org VariableProxy* callee = result->AsVariableProxy(); 3335ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (callee != NULL && 33364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org callee->IsVariable(isolate()->factory()->eval_string())) { 3337c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org top_scope_->DeclarationScope()->RecordEvalCall(); 333843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3339b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewCall(result, args, pos); 334079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org if (fni_ != NULL) fni_->RemoveLastFunction(); 334143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 334243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 334343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 334443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::PERIOD: { 334543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::PERIOD); 334643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int pos = scanner().location().beg_pos; 3347d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org Handle<String> name = ParseIdentifierName(CHECK_OK); 3348b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = 3349b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewProperty(result, factory()->NewLiteral(name), pos); 335065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushLiteralName(name); 335143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 335243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 335343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 335443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 335543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 335643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 335743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 335843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 335943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 336043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3361b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgExpression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { 336243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // NewExpression :: 336343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ('new')+ MemberExpression 336443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 336543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The grammar for new expressions is pretty warped. The keyword 336643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'new' can either be a part of the new expression (where it isn't 336743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // followed by an argument list) or a part of the member expression, 336843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // where it must be followed by an argument list. To accommodate 336943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // this, we parse the 'new' keywords greedily and keep track of how 337043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // many we have parsed. This information is then passed on to the 337143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // member expression parser, which is only allowed to match argument 337243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // lists as long as it has 'new' prefixes left 3373b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Expect(Token::NEW, CHECK_OK); 3374b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org PositionStack::Element pos(stack, scanner().location().beg_pos); 3375b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 3376b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Expression* result; 3377b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org if (peek() == Token::NEW) { 3378b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org result = ParseNewPrefix(stack, CHECK_OK); 3379b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org } else { 3380b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); 338143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 338243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3383b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org if (!stack->is_empty()) { 3384b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org int last = stack->pop(); 3385b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewCallNew( 33867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org result, new(zone()) ZoneList<Expression*>(0, zone()), last); 338743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 338843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 338943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 339043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 339143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3392b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgExpression* Parser::ParseNewExpression(bool* ok) { 3393b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org PositionStack stack(ok); 3394b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org return ParseNewPrefix(&stack, ok); 3395b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 3396b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 3397b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 339843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseMemberExpression(bool* ok) { 3399b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org return ParseMemberWithNewPrefixesExpression(NULL, ok); 340043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 340143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 340243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3403b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgExpression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, 3404b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org bool* ok) { 340543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // MemberExpression :: 340643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // (PrimaryExpression | FunctionLiteral) 340743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ('[' Expression ']' | '.' Identifier | Arguments)* 340843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 340943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse the initial primary or function expression. 341043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* result = NULL; 341143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::FUNCTION) { 341243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::FUNCTION, CHECK_OK); 341343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int function_token_position = scanner().location().beg_pos; 3414e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool is_generator = allow_generators() && Check(Token::MUL); 341543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> name; 341604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool is_strict_reserved_name = false; 341783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (peek_any_identifier()) { 341804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 341904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org CHECK_OK); 342083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 3421dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org FunctionLiteral::FunctionType function_type = name.is_null() 34227c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org ? FunctionLiteral::ANONYMOUS_EXPRESSION 34237c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org : FunctionLiteral::NAMED_EXPRESSION; 34247c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org result = ParseFunctionLiteral(name, 34257c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org is_strict_reserved_name, 3426f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org is_generator, 34277c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org function_token_position, 3428dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org function_type, 34297c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org CHECK_OK); 343043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 343143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParsePrimaryExpression(CHECK_OK); 343243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 343343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 343443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (true) { 343543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (peek()) { 343643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LBRACK: { 343743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::LBRACK); 343843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int pos = scanner().location().beg_pos; 343943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* index = ParseExpression(true, CHECK_OK); 3440b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewProperty(result, index, pos); 344104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (fni_ != NULL) { 344204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (index->IsPropertyName()) { 344304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); 344404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } else { 344504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org fni_->PushLiteralName( 34464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate()->factory()->anonymous_function_string()); 344704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 344804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 344943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACK, CHECK_OK); 345043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 345143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 345243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::PERIOD: { 345343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::PERIOD); 345443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int pos = scanner().location().beg_pos; 3455d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org Handle<String> name = ParseIdentifierName(CHECK_OK); 3456b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = 3457b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewProperty(result, factory()->NewLiteral(name), pos); 345865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushLiteralName(name); 345943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 346043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 346143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LPAREN: { 3462b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org if ((stack == NULL) || stack->is_empty()) return result; 346343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Consume one of the new prefixes (already parsed). 346443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 3465b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org int last = stack->pop(); 3466b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewCallNew(result, args, last); 346743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 346843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 346943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 347043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 347143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 347243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 347343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 347443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 347543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 347643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { 347743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 347843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // contexts this is used as a statement which invokes the debugger as i a 347943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // break point is present. 348043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // DebuggerStatement :: 348143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'debugger' ';' 348243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 348343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::DEBUGGER, CHECK_OK); 348443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExpectSemicolon(CHECK_OK); 3485b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewDebuggerStatement(); 348643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 348743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 348843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 348943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Parser::ReportUnexpectedToken(Token::Value token) { 349043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We don't report stack overflows here, to avoid increasing the 349143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // stack depth even further. Instead we report it after parsing is 3492b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // over, in ParseProgram/ParseJson. 3493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (token == Token::ILLEGAL && stack_overflow_) return; 349443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Four of the tokens are treated specially 349543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (token) { 3496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::EOS: 3497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return ReportMessage("unexpected_eos", Vector<const char*>::empty()); 3498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::NUMBER: 3499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return ReportMessage("unexpected_token_number", 3500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Vector<const char*>::empty()); 3501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::STRING: 3502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return ReportMessage("unexpected_token_string", 3503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Vector<const char*>::empty()); 3504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::IDENTIFIER: 3505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return ReportMessage("unexpected_token_identifier", 3506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Vector<const char*>::empty()); 350783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::FUTURE_RESERVED_WORD: 350804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org return ReportMessage("unexpected_reserved", 350904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org Vector<const char*>::empty()); 3510f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org case Token::YIELD: 351104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org case Token::FUTURE_STRICT_RESERVED_WORD: 35121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return ReportMessage(top_scope_->is_classic_mode() ? 35131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org "unexpected_token_identifier" : 35141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org "unexpected_strict_reserved", 351583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Vector<const char*>::empty()); 3516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: 3517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const char* name = Token::String(token); 3518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(name != NULL); 3519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); 352043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 352143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 352243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 352343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35244a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.comvoid Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { 352583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); 35264a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com const char* element[1] = { *name_string }; 35274a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com ReportMessage("invalid_preparser_data", 35284a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com Vector<const char*>(element, 1)); 35294a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com *ok = false; 35304a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com} 35314a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com 35324a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com 353343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParsePrimaryExpression(bool* ok) { 353443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // PrimaryExpression :: 353543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'this' 353643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'null' 353743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'true' 353843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'false' 353943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Identifier 354043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Number 354143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // String 354243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ArrayLiteral 354343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ObjectLiteral 354443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // RegExpLiteral 354543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '(' Expression ')' 354643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 354743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* result = NULL; 354843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (peek()) { 354943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::THIS: { 355043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::THIS); 3551b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewVariableProxy(top_scope_->receiver()); 355243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 355343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 355443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 355543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::NULL_LITERAL: 355643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::NULL_LITERAL); 3557b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewLiteral(isolate()->factory()->null_value()); 355843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 355943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 356043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::TRUE_LITERAL: 356143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::TRUE_LITERAL); 3562b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewLiteral(isolate()->factory()->true_value()); 356343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 356443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 356543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::FALSE_LITERAL: 356643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::FALSE_LITERAL); 3567b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewLiteral(isolate()->factory()->false_value()); 356843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 356943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 357083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::IDENTIFIER: 3571f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org case Token::YIELD: 357204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org case Token::FUTURE_STRICT_RESERVED_WORD: { 357343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> name = ParseIdentifier(CHECK_OK); 357465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushVariableName(name); 3575bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // The name may refer to a module instance object, so its type is unknown. 3576bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG 3577bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (FLAG_print_interface_details) 3578bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com PrintF("# Variable %s ", name->ToAsciiArray()); 3579bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif 35807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Interface* interface = Interface::NewUnknown(zone()); 3581b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = top_scope_->NewUnresolved( 358228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org factory(), name, interface, scanner().location().beg_pos); 358343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 358443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 358543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 358643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::NUMBER: { 358743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::NUMBER); 35889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org ASSERT(scanner().is_literal_ascii()); 3589a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org double value = StringToDouble(isolate()->unicode_cache(), 3590a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org scanner().literal_ascii_string(), 3591ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ALLOW_HEX | ALLOW_OCTAL | 3592ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); 3593b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewNumberLiteral(value); 359443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 359543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 359643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 359743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::STRING: { 359843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::STRING); 3599bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org Handle<String> symbol = GetSymbol(); 3600b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org result = factory()->NewLiteral(symbol); 360165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushLiteralName(symbol); 360243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 360343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 360443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 360543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::ASSIGN_DIV: 360643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseRegExpLiteral(true, CHECK_OK); 360743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 360843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 360943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::DIV: 361043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseRegExpLiteral(false, CHECK_OK); 361143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 361243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 361343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LBRACK: 361443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseArrayLiteral(CHECK_OK); 361543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 361643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 361743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LBRACE: 361843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseObjectLiteral(CHECK_OK); 361943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 362043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 362143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::LPAREN: 362243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::LPAREN); 3623c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Heuristically try to detect immediately called functions before 3624c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // seeing the call parentheses. 3625c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org parenthesized_function_ = (peek() == Token::FUNCTION); 362643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseExpression(true, CHECK_OK); 362743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 362843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 362943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 363043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::MOD: 3631e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (allow_natives_syntax() || extension_ != NULL) { 363243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = ParseV8Intrinsic(CHECK_OK); 363343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 363443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 363543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we're not allowing special syntax we fall-through to the 363643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // default case. 363743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 363843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: { 3639c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Token::Value tok = Next(); 364043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReportUnexpectedToken(tok); 364143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 364243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 364343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 364443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 364543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 364643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 364743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 364843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 364943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 365043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseArrayLiteral(bool* ok) { 365143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ArrayLiteral :: 365243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '[' Expression? (',' Expression?)* ']' 365343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); 365543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACK, CHECK_OK); 365643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::RBRACK) { 365743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* elem; 365843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() == Token::COMMA) { 365943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen elem = GetLiteralTheHole(); 366043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 366143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen elem = ParseAssignmentExpression(true, CHECK_OK); 366243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 36637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org values->Add(elem, zone()); 366443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::RBRACK) { 366543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COMMA, CHECK_OK); 366643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 366743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 366843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACK, CHECK_OK); 36699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 36709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com // Update the scope information before the pre-parsing bailout. 3671c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org int literal_index = current_function_state_->NextMaterializedLiteralIndex(); 36729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 3673394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Allocate a fixed array to hold all the object literals. 367483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Handle<JSArray> array = 367583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org isolate()->factory()->NewJSArray(0, FAST_HOLEY_SMI_ELEMENTS); 367683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org isolate()->factory()->SetElementsCapacityAndLength( 367783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org array, values->length(), values->length()); 367843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 367943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Fill in the literals. 3680830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Heap* heap = isolate()->heap(); 3681bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org bool is_simple = true; 3682bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org int depth = 1; 368383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org bool is_holey = false; 3684fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org for (int i = 0, n = values->length(); i < n; i++) { 3685fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); 3686bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org if (m_literal != NULL && m_literal->depth() + 1 > depth) { 3687bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org depth = m_literal->depth() + 1; 3688bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 3689fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); 3690830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (boilerplate_value->IsTheHole()) { 369183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org is_holey = true; 36921fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } else if (boilerplate_value->IsUninitialized()) { 3693bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org is_simple = false; 369483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org JSObject::SetOwnElement( 369583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org array, i, handle(Smi::FromInt(0), isolate()), kNonStrictMode); 369643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 369783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org JSObject::SetOwnElement(array, i, boilerplate_value, kNonStrictMode); 369843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 369943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 370043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 370183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Handle<FixedArrayBase> element_values(array->elements()); 370283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 37030b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org // Simple and shallow arrays can be lazily copied, we transform the 37040b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org // elements array to a copy-on-write array. 3705394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (is_simple && depth == 1 && values->length() > 0 && 370683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org array->HasFastSmiOrObjectElements()) { 370783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org element_values->set_map(heap->fixed_cow_array_map()); 37080b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org } 37090b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 3710394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Remember both the literal's constant values as well as the ElementsKind 3711394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // in a 2-element FixedArray. 371283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Handle<FixedArray> literals = isolate()->factory()->NewFixedArray(2, TENURED); 3713394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 371483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ElementsKind kind = array->GetElementsKind(); 371583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org kind = is_holey ? GetHoleyElementsKind(kind) : GetPackedElementsKind(kind); 3716830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org 371783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org literals->set(0, Smi::FromInt(kind)); 3718394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com literals->set(1, *element_values); 3719394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 3720b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewArrayLiteral( 3721b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org literals, values, literal_index, is_simple, depth); 372243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 372343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 372443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 37259258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.orgbool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { 37269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org return property != NULL && 37279258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org property->kind() != ObjectLiteral::Property::PROTOTYPE; 37289258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org} 37299258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 37309258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 3731bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgbool CompileTimeValue::IsCompileTimeValue(Expression* expression) { 3732a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (expression->AsLiteral() != NULL) return true; 3733bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org MaterializedLiteral* lit = expression->AsMaterializedLiteral(); 3734bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return lit != NULL && lit->is_simple(); 3735bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3736bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 37370b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 3738bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgHandle<FixedArray> CompileTimeValue::GetValue(Expression* expression) { 3739d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Factory* factory = Isolate::Current()->factory(); 3740bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ASSERT(IsCompileTimeValue(expression)); 3741d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Handle<FixedArray> result = factory->NewFixedArray(2, TENURED); 3742bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ObjectLiteral* object_literal = expression->AsObjectLiteral(); 3743bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org if (object_literal != NULL) { 3744bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ASSERT(object_literal->is_simple()); 3745f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org if (object_literal->fast_elements()) { 3746dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS)); 3747f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } else { 3748dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS)); 3749f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } 3750bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org result->set(kElementsSlot, *object_literal->constant_properties()); 3751bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } else { 3752bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ArrayLiteral* array_literal = expression->AsArrayLiteral(); 3753bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ASSERT(array_literal != NULL && array_literal->is_simple()); 3754dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL)); 37550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org result->set(kElementsSlot, *array_literal->constant_elements()); 3756bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 3757bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return result; 3758bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3759bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3760bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3761dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgCompileTimeValue::LiteralType CompileTimeValue::GetLiteralType( 3762dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<FixedArray> value) { 3763dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); 3764dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org return static_cast<LiteralType>(literal_type->value()); 3765bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3766bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3767bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3768bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgHandle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { 3769bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); 3770bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 3771bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3772bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3773bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgHandle<Object> Parser::GetBoilerplateValue(Expression* expression) { 3774bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org if (expression->AsLiteral() != NULL) { 37751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return expression->AsLiteral()->value(); 3776bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 3777bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org if (CompileTimeValue::IsCompileTimeValue(expression)) { 3778bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return CompileTimeValue::GetValue(expression); 3779bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 37801fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return isolate()->factory()->uninitialized_value(); 37819258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org} 37829258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 3783e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 3784378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Validation per 11.1.5 Object Initialiser 3785378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgclass ObjectLiteralPropertyChecker { 3786378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org public: 37871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) : 3788bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com props_(Literal::Match), 3789378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org parser_(parser), 37901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org language_mode_(language_mode) { 3791378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 3792378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3793378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org void CheckProperty( 3794378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ObjectLiteral::Property* property, 3795378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Scanner::Location loc, 3796378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org bool* ok); 3797378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3798378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org private: 3799378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org enum PropertyKind { 3800378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org kGetAccessor = 0x01, 3801378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org kSetAccessor = 0x02, 3802378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org kAccessor = kGetAccessor | kSetAccessor, 3803378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org kData = 0x04 3804378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org }; 3805378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3806378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org static intptr_t GetPropertyKind(ObjectLiteral::Property* property) { 3807378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org switch (property->kind()) { 3808378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org case ObjectLiteral::Property::GETTER: 3809378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org return kGetAccessor; 3810378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org case ObjectLiteral::Property::SETTER: 3811378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org return kSetAccessor; 3812378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org default: 3813378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org return kData; 3814378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 3815378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 3816378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3817bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com HashMap props_; 3818378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Parser* parser_; 38191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org LanguageMode language_mode_; 3820378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org}; 3821378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3822378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3823378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid ObjectLiteralPropertyChecker::CheckProperty( 3824378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ObjectLiteral::Property* property, 3825378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Scanner::Location loc, 3826378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org bool* ok) { 3827378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ASSERT(property != NULL); 3828bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Literal* literal = property->key(); 3829bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com HashMap::Entry* entry = props_.Lookup(literal, literal->Hash(), true); 3830378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org intptr_t prev = reinterpret_cast<intptr_t> (entry->value); 3831378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org intptr_t curr = GetPropertyKind(property); 3832378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 38331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Duplicate data properties are illegal in strict or extended mode. 38341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (language_mode_ != CLASSIC_MODE && (curr & prev & kData) != 0) { 3835378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org parser_->ReportMessageAt(loc, "strict_duplicate_property", 3836378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Vector<const char*>::empty()); 3837378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org *ok = false; 3838378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org return; 3839378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 3840378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Data property conflicting with an accessor. 3841378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if (((curr & kData) && (prev & kAccessor)) || 3842378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ((prev & kData) && (curr & kAccessor))) { 3843378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org parser_->ReportMessageAt(loc, "accessor_data_property", 3844378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Vector<const char*>::empty()); 3845378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org *ok = false; 3846378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org return; 3847378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 3848378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Two accessors of the same type conflicting 3849378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if ((curr & prev & kAccessor) != 0) { 3850378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org parser_->ReportMessageAt(loc, "accessor_get_set", 3851378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Vector<const char*>::empty()); 3852378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org *ok = false; 3853378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org return; 3854378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 3855378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3856378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Update map 3857378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org entry->value = reinterpret_cast<void*> (prev | curr); 3858378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org *ok = true; 3859378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org} 3860378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 38619258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 3862b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Parser::BuildObjectLiteralConstantProperties( 3863b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ZoneList<ObjectLiteral::Property*>* properties, 3864b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Handle<FixedArray> constant_properties, 3865b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bool* is_simple, 3866f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org bool* fast_elements, 386757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int* depth, 386857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org bool* may_store_doubles) { 3869b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int position = 0; 3870b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Accumulate the value in local variables and store it at the end. 3871b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bool is_simple_acc = true; 3872b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int depth_acc = 1; 3873f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org uint32_t max_element_index = 0; 3874f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org uint32_t elements = 0; 3875b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org for (int i = 0; i < properties->length(); i++) { 3876b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ObjectLiteral::Property* property = properties->at(i); 3877b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (!IsBoilerplateProperty(property)) { 3878b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org is_simple_acc = false; 3879b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org continue; 3880b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3881b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); 3882b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (m_literal != NULL && m_literal->depth() >= depth_acc) { 3883b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org depth_acc = m_literal->depth() + 1; 3884b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3885b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3886b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined 3887b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // value for COMPUTED properties, the real value is filled in at 3888b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // runtime. The enumeration order is maintained. 38891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Object> key = property->key()->value(); 3890b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Handle<Object> value = GetBoilerplateValue(property->value()); 389157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 38921fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // Ensure objects that may, at any point in time, contain fields with double 38931fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // representation are always treated as nested objects. This is true for 38941fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // computed fields (value is undefined), and smi and double literals 38951fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // (value->IsNumber()). 389657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // TODO(verwaest): Remove once we can store them inline. 38971fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org if (FLAG_track_double_fields && 38981fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org (value->IsNumber() || value->IsUninitialized())) { 389957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org *may_store_doubles = true; 390057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 390157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 39021fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org is_simple_acc = is_simple_acc && !value->IsUninitialized(); 3903b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3904f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org // Keep track of the number of elements in the object literal and 3905f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org // the largest element index. If the largest element index is 3906f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org // much larger than the number of elements, creating an object 3907f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org // literal with fast elements will be a waste of space. 3908f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org uint32_t element_index = 0; 3909f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org if (key->IsString() 3910f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org && Handle<String>::cast(key)->AsArrayIndex(&element_index) 3911f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org && element_index > max_element_index) { 3912f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org max_element_index = element_index; 3913f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org elements++; 3914f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } else if (key->IsSmi()) { 3915f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org int key_value = Smi::cast(*key)->value(); 3916f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org if (key_value > 0 3917f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org && static_cast<uint32_t>(key_value) > max_element_index) { 3918f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org max_element_index = key_value; 3919f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } 3920f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org elements++; 3921f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } 3922f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 3923b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Add name, value pair to the fixed array. 3924b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org constant_properties->set(position++, *key); 3925b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org constant_properties->set(position++, *value); 3926b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3927f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org *fast_elements = 3928f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org (max_element_index <= 32) || ((2 * elements) >= max_element_index); 3929b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org *is_simple = is_simple_acc; 3930b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org *depth = depth_acc; 3931b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 3932b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3933b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3934c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.orgObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, 3935c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org bool* ok) { 3936c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // Special handling of getter and setter syntax: 3937c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 3938c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // We have already read the "get" or "set" keyword. 3939c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Token::Value next = Next(); 39405d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org bool is_keyword = Token::IsKeyword(next); 39415d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (next == Token::IDENTIFIER || next == Token::NUMBER || 394283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org next == Token::FUTURE_RESERVED_WORD || 394304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org next == Token::FUTURE_STRICT_RESERVED_WORD || 39445d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org next == Token::STRING || is_keyword) { 39455d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Handle<String> name; 39465d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (is_keyword) { 39474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org name = isolate_->factory()->InternalizeUtf8String(Token::String(next)); 39485d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } else { 3949bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org name = GetSymbol(); 39505d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 3951c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org FunctionLiteral* value = 3952c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org ParseFunctionLiteral(name, 395383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org false, // reserved words are allowed here 3954f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org false, // not a generator 3955c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org RelocInfo::kNoPosition, 39567c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org FunctionLiteral::ANONYMOUS_EXPRESSION, 3957c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org CHECK_OK); 39582efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Allow any number of parameters for compatibilty with JSC. 39595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Specification only allows zero parameters for get and one for set. 3960b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewObjectLiteralProperty(is_getter, value); 3961c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } else { 3962c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org ReportUnexpectedToken(next); 3963c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org *ok = false; 3964c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org return NULL; 3965c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 3966c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org} 3967c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org 3968c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org 396943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseObjectLiteral(bool* ok) { 397043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ObjectLiteral :: 397143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '{' ( 3972d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org // ((IdentifierName | String | Number) ':' AssignmentExpression) 3973d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 397443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // )*[','] '}' 397543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3976fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org ZoneList<ObjectLiteral::Property*>* properties = 39777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); 39789258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org int number_of_boilerplate_properties = 0; 3979ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org bool has_function = false; 398043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 39811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ObjectLiteralPropertyChecker checker(this, top_scope_->language_mode()); 3982378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 398343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 3984378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 398543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (peek() != Token::RBRACE) { 398665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->Enter(); 398765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 398843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Literal* key = NULL; 3989d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org Token::Value next = peek(); 3990378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3991378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Location of the property name token 3992378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Scanner::Location loc = scanner().peek_location(); 3993378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3994d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org switch (next) { 399583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::FUTURE_RESERVED_WORD: 399604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org case Token::FUTURE_STRICT_RESERVED_WORD: 399743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::IDENTIFIER: { 399843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool is_getter = false; 399943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool is_setter = false; 400043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> id = 400104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 400265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushLiteralName(id); 400365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 4004c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if ((is_getter || is_setter) && peek() != Token::COLON) { 4005378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Update loc to point to the identifier 4006378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org loc = scanner().peek_location(); 400743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ObjectLiteral::Property* property = 4008c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org ParseObjectLiteralGetSet(is_getter, CHECK_OK); 4009d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org if (IsBoilerplateProperty(property)) { 40109258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org number_of_boilerplate_properties++; 4011d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org } 4012378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Validate the property. 4013378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org checker.CheckProperty(property, loc, CHECK_OK); 40147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org properties->Add(property, zone()); 401543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 401665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 401765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) { 401865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->Infer(); 401965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->Leave(); 402065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 402143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen continue; // restart the while 402243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 4023c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // Failed to parse as get/set property, so it's just a property 4024c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // called "get" or "set". 4025b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org key = factory()->NewLiteral(id); 402643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 402743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 402843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::STRING: { 4029c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Consume(Token::STRING); 4030bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org Handle<String> string = GetSymbol(); 403165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) fni_->PushLiteralName(string); 403243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t index; 403326c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org if (!string.is_null() && string->AsArrayIndex(&index)) { 4034b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org key = factory()->NewNumberLiteral(index); 4035c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org break; 403643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 4037b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org key = factory()->NewLiteral(string); 403843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 403943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 404043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Token::NUMBER: { 404143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Consume(Token::NUMBER); 40429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org ASSERT(scanner().is_literal_ascii()); 4043a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org double value = StringToDouble(isolate()->unicode_cache(), 4044a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org scanner().literal_ascii_string(), 4045ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ALLOW_HEX | ALLOW_OCTAL | 4046ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); 4047b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org key = factory()->NewNumberLiteral(value); 404843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 404943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 405043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 4051c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if (Token::IsKeyword(next)) { 4052c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Consume(next); 4053bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org Handle<String> string = GetSymbol(); 4054b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org key = factory()->NewLiteral(string); 4055c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } else { 4056c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // Unexpected token. 4057c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Token::Value next = Next(); 4058c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org ReportUnexpectedToken(next); 4059c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org *ok = false; 4060c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org return NULL; 4061c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 406243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 406343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 406443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::COLON, CHECK_OK); 406543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* value = ParseAssignmentExpression(true, CHECK_OK); 406643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 406743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ObjectLiteral::Property* property = 4068812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org new(zone()) ObjectLiteral::Property(key, value, isolate()); 40699258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 4070ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org // Mark top-level object literals that contain function literals and 4071ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org // pretenure the literal so it can be added as a constant function 4072ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org // property. 4073ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org if (top_scope_->DeclarationScope()->is_global_scope() && 4074ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org value->AsFunctionLiteral() != NULL) { 4075ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org has_function = true; 4076c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org value->AsFunctionLiteral()->set_pretenure(); 4077ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 4078ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 40799258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 4080236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; 4081378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Validate the property 4082378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org checker.CheckProperty(property, loc, CHECK_OK); 40837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org properties->Add(property, zone()); 408443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 408543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1240767): Consider allowing trailing comma. 408643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 408765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 408865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (fni_ != NULL) { 408965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->Infer(); 409065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org fni_->Leave(); 409165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 409243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 409343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RBRACE, CHECK_OK); 4094378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 409543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Computation of literal_index must happen before pre parse bailout. 4096c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org int literal_index = current_function_state_->NextMaterializedLiteralIndex(); 409743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4098ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray( 4099ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org number_of_boilerplate_properties * 2, TENURED); 4100b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4101bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org bool is_simple = true; 4102f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org bool fast_elements = true; 4103bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org int depth = 1; 410457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org bool may_store_doubles = false; 4105fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org BuildObjectLiteralConstantProperties(properties, 4106b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org constant_properties, 4107b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org &is_simple, 4108f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org &fast_elements, 410957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org &depth, 411057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org &may_store_doubles); 4111b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewObjectLiteral(constant_properties, 4112b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org properties, 4113b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org literal_index, 4114b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org is_simple, 4115b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org fast_elements, 4116b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org depth, 411757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org may_store_doubles, 4118b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org has_function); 411943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 412043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 412143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 412243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { 41235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org if (!scanner().ScanRegExpPattern(seen_equal)) { 412443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 412543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReportMessage("unterminated_regexp", Vector<const char*>::empty()); 412643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 412743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 412843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 412943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4130c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org int literal_index = current_function_state_->NextMaterializedLiteralIndex(); 413143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 41329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org Handle<String> js_pattern = NextLiteralString(TENURED); 41335f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org scanner().ScanRegExpFlags(); 41349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org Handle<String> js_flags = NextLiteralString(TENURED); 413543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 413643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4137b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index); 413843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 413943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 414043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 414143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenZoneList<Expression*>* Parser::ParseArguments(bool* ok) { 414243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Arguments :: 414343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '(' (AssignmentExpression)*[','] ')' 414443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 41457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); 414643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 414743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool done = (peek() == Token::RPAREN); 414843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!done) { 414943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expression* argument = ParseAssignmentExpression(true, CHECK_OK); 41507028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org result->Add(argument, zone()); 4151876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org if (result->length() > Code::kMaxArguments) { 4152e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org ReportMessageAt(scanner().location(), "too_many_arguments", 4153e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Vector<const char*>::empty()); 4154e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org *ok = false; 4155e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org return NULL; 4156e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 415743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen done = (peek() == Token::RPAREN); 415843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!done) Expect(Token::COMMA, CHECK_OK); 415943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 416043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 4161fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org return result; 416243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 416343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 416443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 41651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgclass SingletonLogger : public ParserRecorder { 41661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org public: 41671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SingletonLogger() : has_error_(false), start_(-1), end_(-1) { } 4168b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org virtual ~SingletonLogger() { } 41691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 41701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org void Reset() { has_error_ = false; } 41711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 41721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual void LogFunction(int start, 41731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int end, 41741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int literals, 41751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int properties, 41761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org LanguageMode mode) { 41771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(!has_error_); 41781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org start_ = start; 41791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org end_ = end; 41801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org literals_ = literals; 41811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org properties_ = properties; 41821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org mode_ = mode; 41831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org }; 41841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 41851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Logs a symbol creation of a literal or identifier. 41861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual void LogAsciiSymbol(int start, Vector<const char> literal) { } 4187154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { } 41881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 41891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Logs an error message and marks the log as containing an error. 41901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Further logging will be ignored, and ExtractData will return a vector 41911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // representing the error only. 41921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual void LogMessage(int start, 41931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int end, 41941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* message, 41951b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* argument_opt) { 4196657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org if (has_error_) return; 41971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org has_error_ = true; 41981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org start_ = start; 41991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org end_ = end; 42001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org message_ = message; 42011b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org argument_opt_ = argument_opt; 42021b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 42031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 42041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual int function_position() { return 0; } 42051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 42061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual int symbol_position() { return 0; } 42071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 42081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual int symbol_ids() { return -1; } 42091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 42101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual Vector<unsigned> ExtractData() { 42111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org UNREACHABLE(); 42121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return Vector<unsigned>(); 42131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 42141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 42151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual void PauseRecording() { } 42161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 42171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org virtual void ResumeRecording() { } 42181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 42191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org bool has_error() { return has_error_; } 42201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 42211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int start() { return start_; } 42221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int end() { return end_; } 42231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int literals() { 42241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(!has_error_); 42251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return literals_; 42261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 42271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int properties() { 42281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(!has_error_); 42291b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return properties_; 42301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 42311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org LanguageMode language_mode() { 42321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(!has_error_); 42331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return mode_; 42341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 42351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* message() { 42361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(has_error_); 42371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return message_; 42381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 42391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* argument_opt() { 42401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(has_error_); 42411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return argument_opt_; 42421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 42431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 42441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org private: 42451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org bool has_error_; 42461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int start_; 42471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int end_; 42481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // For function entries. 42491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int literals_; 42501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int properties_; 42511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org LanguageMode mode_; 42521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // For error messages. 42531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* message_; 42541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* argument_opt_; 42551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org}; 42561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 42571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 4258dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgFunctionLiteral* Parser::ParseFunctionLiteral( 4259dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> function_name, 4260dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org bool name_is_strict_reserved, 4261dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org bool is_generator, 4262dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org int function_token_position, 4263dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org FunctionLiteral::FunctionType function_type, 4264dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org bool* ok) { 426543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Function :: 426643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '(' FormalParameterList? ')' '{' FunctionBody '}' 426743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 42687c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // Anonymous functions were passed either the empty symbol or a null 42697c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // handle as the function name. Remember if we were passed a non-empty 42707c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // handle to decide whether to invoke function name inference. 42717c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org bool should_infer_name = function_name.is_null(); 42727c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 42737c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // We want a non-null handle as the function name. 42747c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org if (should_infer_name) { 42754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org function_name = isolate()->factory()->empty_string(); 427643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 427743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 427843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int num_parameters = 0; 4279b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // Function declarations are function scoped in normal mode, so they are 4280b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // hoisted. In harmony block scoping mode they are block scoped, so they 4281b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // are not hoisted. 4282dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Scope* scope = 4283dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org (function_type == FunctionLiteral::DECLARATION && !is_extended_mode()) 4284394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) 4285394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com : NewScope(top_scope_, FUNCTION_SCOPE); 428604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ZoneList<Statement*>* body = NULL; 42871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int materialized_literal_count = -1; 42881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int expected_property_count = -1; 428904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int handler_count = 0; 429056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org FunctionLiteral::ParameterFlag duplicate_parameters = 429156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org FunctionLiteral::kNoDuplicateParameters; 4292471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ 4293471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ? FunctionLiteral::kIsParenthesized 4294471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org : FunctionLiteral::kNotParenthesized; 4295f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org FunctionLiteral::IsGeneratorFlag generator = is_generator 4296f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ? FunctionLiteral::kIsGenerator 4297f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org : FunctionLiteral::kNotGenerator; 4298b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org AstProperties ast_properties; 429943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse function body. 4300e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org { FunctionState function_state(this, scope, isolate()); 43017c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org top_scope_->SetScopeName(function_name); 430243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4303e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (is_generator) { 4304e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // For generators, allocating variables in contexts is currently a win 4305e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // because it minimizes the work needed to suspend and resume an 4306e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // activation. 4307e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org top_scope_->ForceContextAllocation(); 4308e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4309e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Calling a generator returns a generator object. That object is stored 4310e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // in a temporary variable, a definition that is used by "yield" 4311e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // expressions. Presence of a variable for the generator object in the 4312e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // FunctionState indicates that this function is a generator. 4313e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Handle<String> tempname = isolate()->factory()->InternalizeOneByteString( 4314e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org STATIC_ASCII_VECTOR(".generator_object")); 4315e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); 4316e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org function_state.set_generator_object_variable(temp); 4317e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 4318e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 431943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // FormalParameterList :: 432043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '(' (Identifier)*[','] ')' 432143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LPAREN, CHECK_OK); 4322394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->set_start_position(scanner().location().beg_pos); 43231c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Scanner::Location name_loc = Scanner::Location::invalid(); 43241c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Scanner::Location dupe_loc = Scanner::Location::invalid(); 43251c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Scanner::Location reserved_loc = Scanner::Location::invalid(); 43260a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 432743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool done = (peek() == Token::RPAREN); 432843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!done) { 432904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool is_strict_reserved = false; 433083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Handle<String> param_name = 433104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org ParseIdentifierOrStrictReservedWord(&is_strict_reserved, 433204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org CHECK_OK); 4333378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 4334378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Store locations for possible future error reports. 4335378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { 4336378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org name_loc = scanner().location(); 4337378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 4338378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { 433956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; 4340378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org dupe_loc = scanner().location(); 4341378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 434204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (!reserved_loc.IsValid() && is_strict_reserved) { 434383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org reserved_loc = scanner().location(); 434483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 4345378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 434656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org top_scope_->DeclareParameter(param_name, VAR); 4347fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org num_parameters++; 4348876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org if (num_parameters > Code::kMaxArguments) { 4349d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ReportMessageAt(scanner().location(), "too_many_parameters", 4350d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com Vector<const char*>::empty()); 4351d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com *ok = false; 4352d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com return NULL; 4353d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 435443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen done = (peek() == Token::RPAREN); 435543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!done) Expect(Token::COMMA, CHECK_OK); 435643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 435743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::RPAREN, CHECK_OK); 435843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 435943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::LBRACE, CHECK_OK); 436043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 436143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we have a named function expression, we add a local variable 436243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // declaration to the body of the function with the name of the 436343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function and let it refer to the function itself (closure). 436443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // NOTE: We create a proxy and resolve it here so that in the 436543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // future we can change the AST to only refer to VariableProxies 436643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // instead of Variables and Proxis as is the case now. 436704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Variable* fvar = NULL; 436804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Token::Value fvar_init_op = Token::INIT_CONST; 4369dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org if (function_type == FunctionLiteral::NAMED_EXPRESSION) { 4370ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; 4371ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; 4372ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com fvar = new(zone()) Variable(top_scope_, 4373ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com function_name, fvar_mode, true /* is valid LHS */, 437428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); 4375ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableProxy* proxy = factory()->NewVariableProxy(fvar); 4376ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableDeclaration* fvar_declaration = 4377ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com factory()->NewVariableDeclaration(proxy, fvar_mode, top_scope_); 4378ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com top_scope_->DeclareFunctionVar(fvar_declaration); 437943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 438043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 43811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Determine whether the function will be lazily compiled. 43821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // The heuristics are: 43831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // - It must not have been prohibited by the caller to Parse (some callers 43841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // need a full AST). 43859c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org // - The outer scope must allow lazy compilation of inner functions. 43861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // - The function mustn't be a function expression with an open parenthesis 43871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // before; we consider that a hint that the function will be called 43881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // immediately, and it would be a waste of time to make it lazily 43891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // compiled. 43901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // These are all things we can know at this point, without looking at the 43911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // function itself. 4392c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bool is_lazily_compiled = (mode() == PARSE_LAZILY && 43939c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org top_scope_->AllowsLazyCompilation() && 43941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org !parenthesized_function_); 4395c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org parenthesized_function_ = false; // The bit was set for this function only. 439643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4397d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (is_lazily_compiled) { 4398d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org int function_block_pos = scanner().location().beg_pos; 43991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org FunctionEntry entry; 4400e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (pre_parse_data_ != NULL) { 4401e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If we have pre_parse_data_, we use it to skip parsing the function 4402e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // body. The preparser data contains the information we need to 4403e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // construct the lazy function. 4404e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org entry = pre_parse_data()->GetFunctionEntry(function_block_pos); 44051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (entry.is_valid()) { 44061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (entry.end_pos() <= function_block_pos) { 44071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // End position greater than end of stream is safe, and hard 44081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // to check. 44091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ReportInvalidPreparseData(function_name, CHECK_OK); 44101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 44111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org scanner().SeekForward(entry.end_pos() - 1); 44121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 44131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org scope->set_end_position(entry.end_pos()); 44141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Expect(Token::RBRACE, CHECK_OK); 44151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org isolate()->counters()->total_preparse_skipped()->Increment( 44161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org scope->end_position() - function_block_pos); 44171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org materialized_literal_count = entry.literal_count(); 44181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org expected_property_count = entry.property_count(); 44191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org top_scope_->SetLanguageMode(entry.language_mode()); 44201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } else { 44211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org is_lazily_compiled = false; 44221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 4423d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } else { 44241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // With no preparser data, we partially parse the function, without 44251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // building an AST. This gathers the data needed to build a lazy 44261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // function. 44271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SingletonLogger logger; 44281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org preparser::PreParser::PreParseResult result = 44291b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org LazyParseFunctionLiteral(&logger); 44301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (result == preparser::PreParser::kPreParseStackOverflow) { 44311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Propagate stack overflow. 44321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org stack_overflow_ = true; 44331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org *ok = false; 44341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return NULL; 4435d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 44361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (logger.has_error()) { 44371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org const char* arg = logger.argument_opt(); 44381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Vector<const char*> args; 44391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (arg != NULL) { 44401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org args = Vector<const char*>(&arg, 1); 44411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 44421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ReportMessageAt(Scanner::Location(logger.start(), logger.end()), 44431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org logger.message(), args); 44441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org *ok = false; 44451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return NULL; 44461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 44471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org scope->set_end_position(logger.end()); 44481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Expect(Token::RBRACE, CHECK_OK); 4449d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org isolate()->counters()->total_preparse_skipped()->Increment( 4450394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->end_position() - function_block_pos); 44511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org materialized_literal_count = logger.literals(); 44521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org expected_property_count = logger.properties(); 44531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org top_scope_->SetLanguageMode(logger.language_mode()); 44544a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com } 4455d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 4456d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 4457d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (!is_lazily_compiled) { 4458471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 44597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org body = new(zone()) ZoneList<Statement*>(8, zone()); 446004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org if (fvar != NULL) { 446128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org VariableProxy* fproxy = top_scope_->NewUnresolved( 446228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org factory(), function_name, Interface::NewConst()); 446304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org fproxy->BindTo(fvar); 4464b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org body->Add(factory()->NewExpressionStatement( 4465b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewAssignment(fvar_init_op, 4466b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org fproxy, 4467b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewThisFunction(), 44687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org RelocInfo::kNoPosition)), 4469471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org zone()); 447004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org } 4471e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4472e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // For generators, allocate and yield an iterator on function entry. 4473e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (is_generator) { 4474e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ZoneList<Expression*>* arguments = 4475e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org new(zone()) ZoneList<Expression*>(0, zone()); 4476e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CallRuntime* allocation = factory()->NewCallRuntime( 4477e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org isolate()->factory()->empty_string(), 4478e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), 4479e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org arguments); 4480e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org VariableProxy* init_proxy = factory()->NewVariableProxy( 4481e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org current_function_state_->generator_object_variable()); 4482e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Assignment* assignment = factory()->NewAssignment( 4483e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); 4484e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org VariableProxy* get_proxy = factory()->NewVariableProxy( 4485e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org current_function_state_->generator_object_variable()); 4486e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Yield* yield = factory()->NewYield( 448777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); 4488e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org body->Add(factory()->NewExpressionStatement(yield), zone()); 4489e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 4490e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 449133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); 4492fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org 449377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (is_generator) { 449477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org VariableProxy* get_proxy = factory()->NewVariableProxy( 449577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org current_function_state_->generator_object_variable()); 449677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Expression *undefined = factory()->NewLiteral( 449777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org isolate()->factory()->undefined_value()); 449877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Yield* yield = factory()->NewYield( 449977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); 450077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org body->Add(factory()->NewExpressionStatement(yield), zone()); 450177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 450277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 4503c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org materialized_literal_count = function_state.materialized_literal_count(); 4504c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org expected_property_count = function_state.expected_property_count(); 450504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org handler_count = function_state.handler_count(); 450643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4507d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Expect(Token::RBRACE, CHECK_OK); 4508394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->set_end_position(scanner().location().end_pos); 450943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 451043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45110a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Validate strict mode. 45121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!top_scope_->is_classic_mode()) { 45137c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org if (IsEvalOrArguments(function_name)) { 4514394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int start_pos = scope->start_position(); 45150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org int position = function_token_position != RelocInfo::kNoPosition 4516378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ? function_token_position 4517378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org : (start_pos > 0 ? start_pos - 1 : start_pos); 451883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Scanner::Location location = Scanner::Location(position, start_pos); 451983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ReportMessageAt(location, 45200a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org "strict_function_name", Vector<const char*>::empty()); 45210a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org *ok = false; 45220a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return NULL; 45230a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 4524378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if (name_loc.IsValid()) { 4525378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ReportMessageAt(name_loc, "strict_param_name", 4526378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Vector<const char*>::empty()); 4527378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org *ok = false; 4528378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org return NULL; 4529378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 4530378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if (dupe_loc.IsValid()) { 4531378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ReportMessageAt(dupe_loc, "strict_param_dupe", 4532378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Vector<const char*>::empty()); 4533378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org *ok = false; 4534378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org return NULL; 4535378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 453604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (name_is_strict_reserved) { 4537394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int start_pos = scope->start_position(); 453883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org int position = function_token_position != RelocInfo::kNoPosition 453983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ? function_token_position 454083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org : (start_pos > 0 ? start_pos - 1 : start_pos); 454183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Scanner::Location location = Scanner::Location(position, start_pos); 454283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ReportMessageAt(location, "strict_reserved_word", 454383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Vector<const char*>::empty()); 454483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org *ok = false; 454583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org return NULL; 454683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 454783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (reserved_loc.IsValid()) { 454883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ReportMessageAt(reserved_loc, "strict_reserved_word", 454983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Vector<const char*>::empty()); 455083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org *ok = false; 455183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org return NULL; 455283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 4553394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com CheckOctalLiteral(scope->start_position(), 4554394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scope->end_position(), 4555394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com CHECK_OK); 45560a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 4557b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org ast_properties = *factory()->visitor()->ast_properties(); 455844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 45590a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 45601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (is_extended_mode()) { 45611805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org CheckConflictingVarDeclarations(scope, CHECK_OK); 45621805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 45631805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 456444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org FunctionLiteral* function_literal = 4565b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewFunctionLiteral(function_name, 4566b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org scope, 4567b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org body, 4568b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org materialized_literal_count, 4569b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org expected_property_count, 4570b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org handler_count, 4571b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org num_parameters, 457256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org duplicate_parameters, 4573dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org function_type, 4574471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FunctionLiteral::kIsFunction, 4575f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org parenthesized, 4576f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org generator); 457744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org function_literal->set_function_token_position(function_token_position); 4578b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org function_literal->set_ast_properties(&ast_properties); 45795d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org 45807c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 458144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return function_literal; 458243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 458343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 458443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgpreparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral( 45861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SingletonLogger* logger) { 45871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); 45881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT_EQ(Token::LBRACE, scanner().current_token()); 45891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 45901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (reusable_preparser_ == NULL) { 45911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org intptr_t stack_limit = isolate()->stack_guard()->real_climit(); 45921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org reusable_preparser_ = new preparser::PreParser(&scanner_, 45931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org NULL, 4594e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org stack_limit); 4595e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); 4596e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_modules(allow_modules()); 4597e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); 4598e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_lazy(true); 4599e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reusable_preparser_->set_allow_generators(allow_generators()); 46001fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org reusable_preparser_->set_allow_for_of(allow_for_of()); 4601ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org reusable_preparser_->set_allow_harmony_numeric_literals( 4602ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org allow_harmony_numeric_literals()); 46031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 46041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org preparser::PreParser::PreParseResult result = 46051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), 4606f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org is_generator(), 46071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org logger); 46081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return result; 46091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org} 46101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 46111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 461243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseV8Intrinsic(bool* ok) { 461343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // CallRuntime :: 461443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // '%' Identifier Arguments 461543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 461643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::MOD, CHECK_OK); 461743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<String> name = ParseIdentifier(CHECK_OK); 461843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 4619d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 4620d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (extension_ != NULL) { 462143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The extension structures are only accessible while parsing the 462243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // very first time not when reparsing because of lazy compilation. 46234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org top_scope_->DeclarationScope()->ForceEagerCompilation(); 462443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 462543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 46264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org const Runtime::Function* function = Runtime::FunctionForName(name); 462743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4628d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Check for built-in IS_VAR macro. 4629d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (function != NULL && 4630d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->intrinsic_type == Runtime::RUNTIME && 4631d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->function_id == Runtime::kIS_VAR) { 4632d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // %IS_VAR(x) evaluates to x if x is a variable, 4633d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // leads to a parse error otherwise. Could be implemented as an 4634d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // inline function %_IS_VAR(x) to eliminate this special case. 4635d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { 4636d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com return args->at(0); 4637d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } else { 4638f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ReportMessage("not_isvar", Vector<const char*>::empty()); 4639d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com *ok = false; 464043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 464143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 464243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 464343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4644d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Check that the expected number of arguments are being passed. 4645d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (function != NULL && 4646d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->nargs != -1 && 4647d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com function->nargs != args->length()) { 4648d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com ReportMessage("illegal_access", Vector<const char*>::empty()); 4649d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com *ok = false; 4650d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com return NULL; 4651de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org } 4652de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 4653de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org // Check that the function is defined if it's an inline runtime call. 4654de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org if (function == NULL && name->Get(0) == '_') { 4655de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); 4656de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org *ok = false; 4657de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org return NULL; 4658f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } 4659f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 4660d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // We have a valid intrinsics call or a call to a builtin. 4661b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewCallRuntime(name, function, args); 466243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 466343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 466443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 466583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgbool Parser::peek_any_identifier() { 466683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Token::Value next = peek(); 466783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org return next == Token::IDENTIFIER || 466804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org next == Token::FUTURE_RESERVED_WORD || 4669f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org next == Token::FUTURE_STRICT_RESERVED_WORD || 4670f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org next == Token::YIELD; 467183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org} 467283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 467383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 467443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Parser::Consume(Token::Value token) { 467543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value next = Next(); 467643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen USE(next); 467743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen USE(token); 467843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(next == token); 467943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 468043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 468143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 468243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Parser::Expect(Token::Value token, bool* ok) { 468343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value next = Next(); 468443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (next == token) return; 468543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReportUnexpectedToken(next); 468643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *ok = false; 468743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 468843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 468943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4690b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgbool Parser::Check(Token::Value token) { 4691b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Token::Value next = peek(); 4692b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (next == token) { 4693b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Consume(next); 4694b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return true; 4695b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4696b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return false; 4697b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4698b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4699b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 47001fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgbool Parser::CheckContextualKeyword(Vector<const char> keyword) { 47011fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org if (peek() == Token::IDENTIFIER && 47021fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org scanner().is_next_contextual_keyword(keyword)) { 47031fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Consume(Token::IDENTIFIER); 47041fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return true; 47051fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org } 47061fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org return false; 47071fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org} 47081fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 47091fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 471043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Parser::ExpectSemicolon(bool* ok) { 471143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check for automatic semicolon insertion according to 471243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // the rules given in ECMA-262, section 7.9, page 21. 471343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Token::Value tok = peek(); 471443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tok == Token::SEMICOLON) { 471543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 471643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 471743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 4718df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org if (scanner().HasAnyLineTerminatorBeforeNext() || 471943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tok == Token::RBRACE || 472043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tok == Token::EOS) { 472143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 472243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 472343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Expect(Token::SEMICOLON, ok); 472443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 472543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 472643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47271fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid Parser::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { 4728812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Expect(Token::IDENTIFIER, ok); 4729812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org if (!*ok) return; 47301fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org if (!scanner().is_literal_contextual_keyword(keyword)) { 4731812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org *ok = false; 4732812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ReportUnexpectedToken(scanner().current_token()); 4733812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 4734812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 4735812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 4736812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 473743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenLiteral* Parser::GetLiteralUndefined() { 4738b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewLiteral(isolate()->factory()->undefined_value()); 473943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 474043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 474143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 474243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenLiteral* Parser::GetLiteralTheHole() { 4743b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewLiteral(isolate()->factory()->the_hole_value()); 474443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 474543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 474643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4747b645116853c677aca8a316381b87441ba6004f67danno@chromium.org// Parses an identifier that is valid for the current scope, in particular it 474804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// fails on strict mode future reserved keywords in a strict scope. 474943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<String> Parser::ParseIdentifier(bool* ok) { 4750f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Token::Value next = Next(); 4751f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (next == Token::IDENTIFIER || 4752f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org (top_scope_->is_classic_mode() && 4753f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org (next == Token::FUTURE_STRICT_RESERVED_WORD || 4754f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org (next == Token::YIELD && !is_generator())))) { 4755bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org return GetSymbol(); 4756f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } else { 4757f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ReportUnexpectedToken(next); 4758f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org *ok = false; 4759f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return Handle<String>(); 476004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 476183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org} 476283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 476383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 476404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// Parses and identifier or a strict mode future reserved word, and indicate 476504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// whether it is strict mode future reserved. 476604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgHandle<String> Parser::ParseIdentifierOrStrictReservedWord( 476704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool* is_strict_reserved, bool* ok) { 4768f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Token::Value next = Next(); 4769f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (next == Token::IDENTIFIER) { 4770f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org *is_strict_reserved = false; 4771f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || 4772f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org (next == Token::YIELD && !is_generator())) { 477304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org *is_strict_reserved = true; 4774f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } else { 4775f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ReportUnexpectedToken(next); 4776f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org *ok = false; 4777f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return Handle<String>(); 477883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 4779bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org return GetSymbol(); 478043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 478143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4782d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org 4783d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.orgHandle<String> Parser::ParseIdentifierName(bool* ok) { 4784d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org Token::Value next = Next(); 478583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (next != Token::IDENTIFIER && 478604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org next != Token::FUTURE_RESERVED_WORD && 478704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org next != Token::FUTURE_STRICT_RESERVED_WORD && 478804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org !Token::IsKeyword(next)) { 4789d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org ReportUnexpectedToken(next); 4790d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org *ok = false; 4791d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org return Handle<String>(); 4792d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org } 4793bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org return GetSymbol(); 4794d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org} 4795d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org 4796378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 479764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid Parser::MarkAsLValue(Expression* expression) { 479864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org VariableProxy* proxy = expression != NULL 479964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ? expression->AsVariableProxy() 480064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org : NULL; 480164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 480264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (proxy != NULL) proxy->MarkAsLValue(); 480364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 480464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 480564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 4806378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Checks LHS expression for assignment and prefix/postfix increment/decrement 4807378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// in strict mode. 4808378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid Parser::CheckStrictModeLValue(Expression* expression, 4809378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org const char* error, 4810378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org bool* ok) { 48111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(!top_scope_->is_classic_mode()); 4812378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org VariableProxy* lhs = expression != NULL 4813378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ? expression->AsVariableProxy() 4814378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org : NULL; 4815378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 4816378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { 4817378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ReportMessage(error, Vector<const char*>::empty()); 4818378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org *ok = false; 4819378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 4820378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org} 4821378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 4822378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 48231c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org// Checks whether an octal literal was last seen between beg_pos and end_pos. 48241c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org// If so, reports an error. Only called for strict mode. 48250ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { 48261c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Scanner::Location octal = scanner().octal_position(); 48271c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org if (octal.IsValid() && 48281c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org beg_pos <= octal.beg_pos && 48291c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org octal.end_pos <= end_pos) { 48301c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org ReportMessageAt(octal, "strict_octal_literal", 48310ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org Vector<const char*>::empty()); 48320ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org scanner().clear_octal_position(); 48330ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org *ok = false; 48340ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 48350ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org} 48360ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4837d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org 48381805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { 48391805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Declaration* decl = scope->CheckConflictingVarDeclarations(); 48401805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org if (decl != NULL) { 48411805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // In harmony mode we treat conflicting variable bindinds as early 48421805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // errors. See ES5 16 for a definition of early errors. 48431805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Handle<String> name = decl->proxy()->name(); 484483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); 48451805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org const char* elms[2] = { "Variable", *c_string }; 48461805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Vector<const char*> args(elms, 2); 48471805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org int position = decl->proxy()->position(); 48481805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Scanner::Location location = position == RelocInfo::kNoPosition 48491805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org ? Scanner::Location::invalid() 48501805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org : Scanner::Location(position, position + 1); 48511805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org ReportMessageAt(location, "redeclaration", args); 48521805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org *ok = false; 48531805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 48541805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org} 48551805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 48561805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 485704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// This function reads an identifier name and determines whether or not it 485883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// is 'get' or 'set'. 485904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgHandle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, 486004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool* is_set, 486104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org bool* ok) { 486204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org Handle<String> result = ParseIdentifierName(ok); 486343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!*ok) return Handle<String>(); 48649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { 48659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org const char* token = scanner().literal_ascii_string().start(); 48669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *is_get = strncmp(token, "get", 3) == 0; 48679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *is_set = !*is_get && strncmp(token, "set", 3) == 0; 486843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 486983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org return result; 487043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 487143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 487243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 487343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 487443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Parser support 487543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 487643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 487743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Parser::TargetStackContainsLabel(Handle<String> label) { 4878b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != NULL; t = t->previous()) { 4879b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org BreakableStatement* stat = t->node()->AsBreakableStatement(); 488043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (stat != NULL && ContainsLabel(stat->labels(), label)) 488143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 488243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 488343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 488443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 488543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 488643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 488743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenBreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { 488843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool anonymous = label.is_null(); 4889b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != NULL; t = t->previous()) { 4890b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org BreakableStatement* stat = t->node()->AsBreakableStatement(); 489143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (stat == NULL) continue; 489243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if ((anonymous && stat->is_target_for_anonymous()) || 489343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen (!anonymous && ContainsLabel(stat->labels(), label))) { 4894b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org RegisterTargetUse(stat->break_target(), t->previous()); 489543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return stat; 489643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 489743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 489843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 489943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 490043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 490143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 490243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenIterationStatement* Parser::LookupContinueTarget(Handle<String> label, 490343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* ok) { 490443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool anonymous = label.is_null(); 4905b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != NULL; t = t->previous()) { 4906b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org IterationStatement* stat = t->node()->AsIterationStatement(); 490743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (stat == NULL) continue; 490843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 490943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(stat->is_target_for_anonymous()); 491043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (anonymous || ContainsLabel(stat->labels(), label)) { 4911b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org RegisterTargetUse(stat->continue_target(), t->previous()); 491243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return stat; 491343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 491443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 491543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 491643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 491743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 491843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 491944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid Parser::RegisterTargetUse(Label* target, Target* stop) { 4920b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org // Register that a break target found at the given stop in the 49217be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org // target stack has been used from the top of the target stack. Add 49227be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org // the break target to any TargetCollectors passed on the stack. 4923b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org for (Target* t = target_stack_; t != stop; t = t->previous()) { 4924b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org TargetCollector* collector = t->node()->AsTargetCollector(); 49257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (collector != NULL) collector->AddTarget(target, zone()); 492643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 492743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 492843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 492943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4930dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgExpression* Parser::NewThrowReferenceError(Handle<String> message) { 49314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return NewThrowError(isolate()->factory()->MakeReferenceError_string(), 4932dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org message, HandleVector<Object>(NULL, 0)); 493343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 493443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 493543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4936dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgExpression* Parser::NewThrowSyntaxError(Handle<String> message, 493743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> first) { 493843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int argc = first.is_null() ? 0 : 1; 493943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc); 4940ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return NewThrowError( 4941dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org isolate()->factory()->MakeSyntaxError_string(), message, arguments); 494243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 494343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 494443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4945dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgExpression* Parser::NewThrowTypeError(Handle<String> message, 494643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> first, 494743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> second) { 494843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(!first.is_null() && !second.is_null()); 494943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> elements[] = { first, second }; 495043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Vector< Handle<Object> > arguments = 495143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HandleVector<Object>(elements, ARRAY_SIZE(elements)); 4952ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return NewThrowError( 4953dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org isolate()->factory()->MakeTypeError_string(), message, arguments); 495443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 495543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 495643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 495743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::NewThrowError(Handle<String> constructor, 4958dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Handle<String> message, 495943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Vector< Handle<Object> > arguments) { 496043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int argc = arguments.length(); 4961ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc, 4962ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org TENURED); 496343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < argc; i++) { 496443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> element = arguments[i]; 496543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!element.is_null()) { 4966496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org elements->set(i, *element); 496743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 496843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 4969fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements( 4970fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org elements, FAST_ELEMENTS, TENURED); 4971496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 49727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone()); 4973dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org args->Add(factory()->NewLiteral(message), zone()); 49747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org args->Add(factory()->NewLiteral(array), zone()); 4975b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org CallRuntime* call_constructor = 4976b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org factory()->NewCallRuntime(constructor, NULL, args); 4977b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return factory()->NewThrow(call_constructor, scanner().location().beg_pos); 497843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 497943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4980e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 4981b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// ---------------------------------------------------------------------------- 4982a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Regular expressions 4983a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4984a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4985a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpParser::RegExpParser(FlatStringReader* in, 4986a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Handle<String>* error, 49875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org bool multiline, 49885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Zone* zone) 4989ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : isolate_(Isolate::Current()), 49905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org zone_(zone), 4991ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org error_(error), 4992ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org captures_(NULL), 4993ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org in_(in), 4994ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org current_(kEndMarker), 4995ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org next_pos_(0), 4996ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org capture_count_(0), 4997ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org has_more_(true), 4998ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org multiline_(multiline), 4999ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org simple_(false), 5000ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org contains_anchor_(false), 5001ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org is_scanned_for_captures_(false), 5002ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org failed_(false) { 5003023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org Advance(); 5004a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5005a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5006a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5007a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::Next() { 5008a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (has_next()) { 5009a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return in()->Get(next_pos_); 5010a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5011a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return kEndMarker; 5012a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5013a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5014a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5015a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5016a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Advance() { 5017a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (next_pos_ < in()->length()) { 5018ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org StackLimitCheck check(isolate()); 5019a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (check.HasOverflowed()) { 5020ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ReportError(CStrVector(Isolate::kStackOverflowMessage)); 50215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else if (zone()->excess_allocation()) { 5022a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ReportError(CStrVector("Regular expression too large")); 5023a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5024a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org current_ = in()->Get(next_pos_); 5025a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org next_pos_++; 5026a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5027a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5028a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org current_ = kEndMarker; 5029a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org has_more_ = false; 5030a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5031a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5032a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5033a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5034a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Reset(int pos) { 5035a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org next_pos_ = pos; 503653ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org has_more_ = (pos < in()->length()); 5037a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5038a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5039a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5040a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5041a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Advance(int dist) { 5042023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org next_pos_ += dist - 1; 5043023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org Advance(); 5044a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5045a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5046a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 504737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.combool RegExpParser::simple() { 504837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return simple_; 5049a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5050a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5051e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 5052a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ReportError(Vector<const char> message) { 5053a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org failed_ = true; 5054ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED); 5055a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Zip to the end to make sure the no more input is read. 5056a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org current_ = kEndMarker; 5057a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org next_pos_ = in()->length(); 5058a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return NULL; 5059a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5060a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5061a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5062a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Pattern :: 5063a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Disjunction 5064a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParsePattern() { 5065a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpTree* result = ParseDisjunction(CHECK_FAILED); 506686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ASSERT(!has_more()); 50677ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org // If the result of parsing is a literal string atom, and it has the 50687ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org // same length as the input, then the atom is identical to the input. 50697ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org if (result->IsAtom() && result->AsAtom()->length() == in()->length()) { 50707ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org simple_ = true; 50717ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org } 5072a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return result; 5073a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5074a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5075a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5076a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Disjunction :: 5077a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Alternative 5078a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Alternative | Disjunction 5079a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Alternative :: 5080a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// [empty] 5081a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Term Alternative 5082a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Term :: 5083a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Assertion 5084a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Atom 5085a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Atom Quantifier 5086a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParseDisjunction() { 508786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Used to store current state while parsing subexpressions. 5088400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org RegExpParserState initial_state(NULL, INITIAL, 0, zone()); 508986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpParserState* stored_state = &initial_state; 509086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Cache the builder in a local variable for quick access. 509186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpBuilder* builder = initial_state.builder(); 5092a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (true) { 5093a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (current()) { 5094a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case kEndMarker: 509586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (stored_state->IsSubexpression()) { 509686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Inside a parenthesized group when hitting end of input. 509786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Unterminated group") CHECK_FAILED); 509886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 509986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ASSERT_EQ(INITIAL, stored_state->group_type()); 510086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Parsing completed successfully. 510186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org return builder->ToRegExp(); 510286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case ')': { 510386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (!stored_state->IsSubexpression()) { 510486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Unmatched ')'") CHECK_FAILED); 510586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 510686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ASSERT_NE(INITIAL, stored_state->group_type()); 510786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 5108a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 510986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // End disjunction parsing and convert builder content to new single 511086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // regexp atom. 511186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpTree* body = builder->ToRegExp(); 511286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 511386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org int end_capture_index = captures_started(); 511486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 511586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org int capture_index = stored_state->capture_index(); 5116dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org SubexpressionType group_type = stored_state->group_type(); 511786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 511886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Restore previous state. 511986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org stored_state = stored_state->previous_state(); 512086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder = stored_state->builder(); 512186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 512286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Build result of subexpression. 5123dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org if (group_type == CAPTURE) { 5124c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index); 512586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org captures_->at(capture_index - 1) = capture; 512686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org body = capture; 5127dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org } else if (group_type != GROUPING) { 5128dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org ASSERT(group_type == POSITIVE_LOOKAHEAD || 5129dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org group_type == NEGATIVE_LOOKAHEAD); 5130dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org bool is_positive = (group_type == POSITIVE_LOOKAHEAD); 5131c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org body = new(zone()) RegExpLookahead(body, 513286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org is_positive, 513386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org end_capture_index - capture_index, 513486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org capture_index); 5135a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 513686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(body); 513749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // For compatability with JSC and ES3, we allow quantifiers after 513849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // lookaheads, and break in all cases. 513986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 514086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 514186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case '|': { 514286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Advance(); 514386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->NewAlternative(); 5144a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 5145a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5146a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '*': 5147a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '+': 5148a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '?': 5149e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return ReportError(CStrVector("Nothing to repeat")); 5150a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '^': { 5151a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5152245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (multiline_) { 515386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 5154c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE)); 5155245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } else { 515686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 5157c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT)); 5158245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org set_contains_anchor(); 5159245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 5160a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 5161a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5162a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '$': { 5163a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5164dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org RegExpAssertion::AssertionType assertion_type = 5165a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org multiline_ ? RegExpAssertion::END_OF_LINE : 5166a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpAssertion::END_OF_INPUT; 5167dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type)); 5168a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 5169a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5170a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '.': { 5171a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5172a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // everything except \x0a, \x0d, \u2028 and \u2029 517340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org ZoneList<CharacterRange>* ranges = 51747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<CharacterRange>(2, zone()); 51757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange::AddClassEscape('.', ranges, zone()); 5176c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); 517786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 5178a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5179a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5180a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '(': { 5181dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org SubexpressionType subexpr_type = CAPTURE; 518286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Advance(); 518386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (current() == '?') { 518486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org switch (Next()) { 518586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case ':': 5186dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org subexpr_type = GROUPING; 518786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 518886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case '=': 5189dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org subexpr_type = POSITIVE_LOOKAHEAD; 519086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 519186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org case '!': 5192dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org subexpr_type = NEGATIVE_LOOKAHEAD; 519386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 519486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org default: 519586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Invalid group") CHECK_FAILED); 519686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 519786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 519886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Advance(2); 519986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } else { 520086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (captures_ == NULL) { 52017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone()); 520286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 520386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (captures_started() >= kMaxCaptures) { 520486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org ReportError(CStrVector("Too many captures") CHECK_FAILED); 520586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 52067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org captures_->Add(NULL, zone()); 520786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 520886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Store current state and begin new disjunction parsing. 5209dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type, 5210400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org captures_started(), zone()); 521186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder = stored_state->builder(); 521249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org continue; 5213a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5214a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '[': { 5215a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpTree* atom = ParseCharacterClass(CHECK_FAILED); 521686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 5217a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5218a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5219a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Atom :: 5220a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // \ AtomEscape 5221a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '\\': 5222a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (Next()) { 5223a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case kEndMarker: 5224e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return ReportError(CStrVector("\\ at end of pattern")); 5225a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'b': 5226a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 522786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 5228c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY)); 5229a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 5230a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'B': 5231a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 523286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAssertion( 5233c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY)); 5234a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 523549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // AtomEscape :: 523649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // CharacterClassEscape 523749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // 523849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // CharacterClassEscape :: one of 523949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // d D s S w W 5240a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'd': case 'D': case 's': case 'S': case 'w': case 'W': { 5241a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = Next(); 5242a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 524340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org ZoneList<CharacterRange>* ranges = 52447028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<CharacterRange>(2, zone()); 52457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange::AddClassEscape(c, ranges, zone()); 5246c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); 524786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 524886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 5249a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5250a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '1': case '2': case '3': case '4': case '5': case '6': 5251a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '7': case '8': case '9': { 5252a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int index = 0; 5253a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseBackReferenceIndex(&index)) { 525486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org RegExpCapture* capture = NULL; 525586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (captures_ != NULL && index <= captures_->length()) { 525686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org capture = captures_->at(index - 1); 525786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 525886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org if (capture == NULL) { 525986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddEmpty(); 526086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 5261a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5262c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RegExpTree* atom = new(zone()) RegExpBackReference(capture); 526386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddAtom(atom); 526486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org break; 5265a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5266a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 first_digit = Next(); 5267a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (first_digit == '8' || first_digit == '9') { 5268a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Treat as identity escape 526986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(first_digit); 5270a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5271a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5272a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5273a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5274a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // FALLTHROUGH 5275a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '0': { 5276a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5277a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 octal = ParseOctalLiteral(); 527886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(octal); 5279a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5280a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5281a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // ControlEscape :: one of 5282a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // f n r t v 5283a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'f': 5284a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 528586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\f'); 5286a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5287a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'n': 5288a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 528986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\n'); 5290a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5291a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'r': 5292a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 529386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\r'); 5294a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5295a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 't': 5296a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 529786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\t'); 5298a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5299a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'v': 5300a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 530186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('\v'); 5302a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5303a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'c': { 5304d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Advance(); 5305d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 controlLetter = Next(); 5306d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Special case if it is an ASCII letter. 5307d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Convert lower case letters to uppercase. 5308d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 letter = controlLetter & ~('a' ^ 'A'); 5309d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if (letter < 'A' || 'Z' < letter) { 5310d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // controlLetter is not in range 'A'-'Z' or 'a'-'z'. 5311d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // This is outside the specification. We match JSC in 5312d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // reading the backslash as a literal character instead 5313d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // of as starting an escape. 5314d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org builder->AddCharacter('\\'); 5315d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } else { 5316d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Advance(2); 5317d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org builder->AddCharacter(controlLetter & 0x1f); 5318d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 5319a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5320a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5321a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'x': { 5322a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5323a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 5324a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(2, &value)) { 532586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(value); 5326a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 532786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('x'); 5328a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5329a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5330a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5331a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'u': { 5332a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5333a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 5334a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(4, &value)) { 533586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(value); 5336a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 533786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter('u'); 5338a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5339a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5340a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5341a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 5342a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Identity escape. 534386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(Next()); 5344a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5345a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5346a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5347a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5348a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '{': { 5349a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int dummy; 5350a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseIntervalQuantifier(&dummy, &dummy)) { 5351a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ReportError(CStrVector("Nothing to repeat") CHECK_FAILED); 5352a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5353a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // fallthrough 5354a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5355a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 535686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org builder->AddCharacter(current()); 5357a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5358a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5359a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } // end switch(current()) 5360a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5361a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int min; 5362a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int max; 5363a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (current()) { 5364a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // QuantifierPrefix :: 5365a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // * 5366a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // + 5367a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // ? 5368a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // { 5369a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '*': 5370a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org min = 0; 537137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com max = RegExpTree::kInfinity; 5372a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5373a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5374a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '+': 5375a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org min = 1; 537637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com max = RegExpTree::kInfinity; 5377a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5378a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5379a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '?': 5380a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org min = 0; 5381a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org max = 1; 5382a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5383a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5384a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '{': 5385a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseIntervalQuantifier(&min, &max)) { 5386245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (max < min) { 5387245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org ReportError(CStrVector("numbers out of order in {} quantifier.") 5388245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org CHECK_FAILED); 5389245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 5390a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5391a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5392a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 5393a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5394a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 5395a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org continue; 5396a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5397dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY; 5398a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '?') { 5399dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org quantifier_type = RegExpQuantifier::NON_GREEDY; 54000c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Advance(); 54010c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } else if (FLAG_regexp_possessive_quantifier && current() == '+') { 54020c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // FLAG_regexp_possessive_quantifier is a debug-only flag. 5403dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org quantifier_type = RegExpQuantifier::POSSESSIVE; 5404a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5405a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5406dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org builder->AddQuantifierToAtom(min, max, quantifier_type); 5407a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5408a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5409a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5410a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5411a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifdef DEBUG 5412a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Currently only used in an ASSERT. 5413a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatic bool IsSpecialClassEscape(uc32 c) { 5414a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (c) { 5415a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'd': case 'D': 5416a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 's': case 'S': 5417a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'w': case 'W': 5418a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 5419a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 5420a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5421a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5422a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5423a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif 5424a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5425a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5426a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// In order to know whether an escape is a backreference or not we have to scan 5427a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// the entire regexp and find the number of capturing parentheses. However we 5428a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// don't want to scan the regexp twice unless it is necessary. This mini-parser 5429a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// is called when needed. It can see the difference between capturing and 5430a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// noncapturing parentheses and can skip character classes and backslash-escaped 5431a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// characters. 5432a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::ScanForCaptures() { 5433a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Start with captures started previous to current position 5434a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int capture_count = captures_started(); 5435a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Add count of captures after this position. 5436a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int n; 5437a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while ((n = current()) != kEndMarker) { 5438a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5439a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (n) { 5440a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '\\': 5441a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5442a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5443a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '[': { 5444a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int c; 5445a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while ((c = current()) != kEndMarker) { 5446a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5447a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (c == '\\') { 5448a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5449a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5450a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (c == ']') break; 5451a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5452a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5453a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5454a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5455a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '(': 5456a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() != '?') capture_count++; 5457a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5458a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5459a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5460a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org capture_count_ = capture_count; 5461a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org is_scanned_for_captures_ = true; 5462a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5463a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5464a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5465a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseBackReferenceIndex(int* index_out) { 5466a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT_EQ('\\', current()); 5467a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT('1' <= Next() && Next() <= '9'); 5468245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // Try to parse a decimal literal that is no greater than the total number 5469245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // of left capturing parentheses in the input. 5470a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int start = position(); 5471a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int value = Next() - '0'; 5472a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5473a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (true) { 5474a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = current(); 5475a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (IsDecimalDigit(c)) { 5476a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org value = 10 * value + (c - '0'); 5477245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (value > kMaxCaptures) { 5478245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org Reset(start); 5479245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org return false; 5480245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 5481a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5482a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5483a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5484a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5485a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5486a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (value > captures_started()) { 5487a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!is_scanned_for_captures_) { 5488a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int saved_position = position(); 5489a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ScanForCaptures(); 5490a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(saved_position); 5491a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5492a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (value > capture_count_) { 5493a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 5494a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5495a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5496a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5497a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *index_out = value; 5498a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 5499a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5500a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5501a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5502a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// QuantifierPrefix :: 5503a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// { DecimalDigits } 5504a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// { DecimalDigits , } 5505a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// { DecimalDigits , DecimalDigits } 5506245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// 5507245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// Returns true if parsing succeeds, and set the min_out and max_out 5508245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// values. Values are truncated to RegExpTree::kInfinity if they overflow. 5509a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) { 5510a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT_EQ(current(), '{'); 5511a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int start = position(); 5512a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5513a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int min = 0; 5514a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!IsDecimalDigit(current())) { 5515a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 5516a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5517a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5518a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (IsDecimalDigit(current())) { 5519245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org int next = current() - '0'; 5520245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (min > (RegExpTree::kInfinity - next) / 10) { 5521245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // Overflow. Skip past remaining decimal digits and return -1. 5522245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org do { 5523245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org Advance(); 5524245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } while (IsDecimalDigit(current())); 5525245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org min = RegExpTree::kInfinity; 5526245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org break; 5527245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 5528245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org min = 10 * min + next; 5529a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5530a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5531a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int max = 0; 5532a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '}') { 5533a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org max = min; 5534a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5535a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (current() == ',') { 5536a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5537a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '}') { 553837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com max = RegExpTree::kInfinity; 5539a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5540a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5541a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (IsDecimalDigit(current())) { 5542245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org int next = current() - '0'; 5543245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (max > (RegExpTree::kInfinity - next) / 10) { 5544245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org do { 5545245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org Advance(); 5546245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } while (IsDecimalDigit(current())); 5547245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org max = RegExpTree::kInfinity; 5548245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org break; 5549245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 5550245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org max = 10 * max + next; 5551a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5552a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5553a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() != '}') { 5554a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 5555a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5556a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5557a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5558a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5559a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5560a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 5561a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5562a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5563a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *min_out = min; 5564a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *max_out = max; 5565a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 5566a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5567a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5568a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5569a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::ParseOctalLiteral() { 5570a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT('0' <= current() && current() <= '7'); 5571a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // For compatibility with some other browsers (not all), we parse 5572a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // up to three octal digits with a value below 256. 5573a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value = current() - '0'; 5574a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5575a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if ('0' <= current() && current() <= '7') { 5576a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org value = value * 8 + current() - '0'; 5577a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5578a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (value < 32 && '0' <= current() && current() <= '7') { 5579a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org value = value * 8 + current() - '0'; 5580a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5581a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5582a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5583a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return value; 5584a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5585a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5586a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5587a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseHexEscape(int length, uc32 *value) { 5588a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int start = position(); 5589a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 val = 0; 5590a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org bool done = false; 5591a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org for (int i = 0; !done; i++) { 5592a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = current(); 5593a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int d = HexValue(c); 5594a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (d < 0) { 5595a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Reset(start); 5596a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 5597a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5598a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org val = val * 16 + d; 5599a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5600a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (i == length - 1) { 5601a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org done = true; 5602a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5603a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5604a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *value = val; 5605a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 5606a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5607a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5608a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5609a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::ParseClassCharacterEscape() { 5610a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(current() == '\\'); 5611a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(has_next() && !IsSpecialClassEscape(Next())); 5612a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5613a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (current()) { 5614a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'b': 5615a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5616a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\b'; 5617a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // ControlEscape :: one of 5618a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // f n r t v 5619a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'f': 5620a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5621a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\f'; 5622a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'n': 5623a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5624a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\n'; 5625a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'r': 5626a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5627a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\r'; 5628a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 't': 5629a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5630a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\t'; 5631a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'v': 5632a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5633a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return '\v'; 5634d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org case 'c': { 5635d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 controlLetter = Next(); 5636d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org uc32 letter = controlLetter & ~('A' ^ 'a'); 5637d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // For compatibility with JSC, inside a character class 5638d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // we also accept digits and underscore as control characters. 5639d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if ((controlLetter >= '0' && controlLetter <= '9') || 5640d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org controlLetter == '_' || 5641d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org (letter >= 'A' && letter <= 'Z')) { 5642d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Advance(2); 5643d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Control letters mapped to ASCII control characters in the range 5644d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // 0x00-0x1f. 5645d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org return controlLetter & 0x1f; 5646d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 5647d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // We match JSC in reading the backslash as a literal 5648d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // character instead of as starting an escape. 5649d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org return '\\'; 5650d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 5651a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '0': case '1': case '2': case '3': case '4': case '5': 5652a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case '6': case '7': 5653a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // For compatibility, we interpret a decimal escape that isn't 5654a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // a back reference (and therefore either \0 or not valid according 5655a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // to the specification) as a 1..3 digit octal character code. 5656a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return ParseOctalLiteral(); 5657a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'x': { 5658a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5659a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 5660a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(2, &value)) { 5661a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return value; 5662a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5663a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // If \x is not followed by a two-digit hexadecimal, treat it 5664a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // as an identity escape. 5665a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return 'x'; 5666a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5667a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'u': { 5668a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5669a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 value; 5670a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ParseHexEscape(4, &value)) { 5671a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return value; 5672a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5673a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // If \u is not followed by a four-digit hexadecimal, treat it 5674a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // as an identity escape. 5675a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return 'u'; 5676a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5677a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: { 5678a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Extended identity escape. We accept any character that hasn't 5679a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // been matched by a more specific case, not just the subset required 5680a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // by the ECMAScript specification. 5681a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 result = current(); 5682a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5683a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return result; 5684a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5685a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5686a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return 0; 5687a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5688a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5689a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5690a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgCharacterRange RegExpParser::ParseClassAtom(uc16* char_class) { 5691a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT_EQ(0, *char_class); 5692a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 first = current(); 5693a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (first == '\\') { 5694a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (Next()) { 5695a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case 'w': case 'W': case 'd': case 'D': case 's': case 'S': { 5696a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *char_class = Next(); 5697a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(2); 5698a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return CharacterRange::Singleton(0); // Return dummy value. 5699a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 570037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com case kEndMarker: 5701e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return ReportError(CStrVector("\\ at end of pattern")); 5702a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 5703a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc32 c = ParseClassCharacterEscape(CHECK_FAILED); 5704a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return CharacterRange::Singleton(c); 5705a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5706a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 5707a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5708a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return CharacterRange::Singleton(first); 5709a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5710a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5711a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5712a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 571314a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.orgstatic const uc16 kNoCharClass = 0; 571414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org 571514a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// Adds range or pre-defined character class to character ranges. 571614a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// If char_class is not kInvalidClass, it's interpreted as a class 571714a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// escape (i.e., 's' means whitespace, from '\s'). 571814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.orgstatic inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges, 571914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org uc16 char_class, 57207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange range, 57217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Zone* zone) { 572214a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org if (char_class != kNoCharClass) { 57237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CharacterRange::AddClassEscape(char_class, ranges, zone); 572414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org } else { 57257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(range, zone); 572614a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org } 572714a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org} 572814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org 572914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org 5730a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParseCharacterClass() { 5731a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org static const char* kUnterminated = "Unterminated character class"; 5732a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org static const char* kRangeOutOfOrder = "Range out of order in character class"; 5733a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5734a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT_EQ(current(), '['); 5735a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5736a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org bool is_negated = false; 5737a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '^') { 5738a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org is_negated = true; 5739a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5740a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 57417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<CharacterRange>* ranges = 57427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) ZoneList<CharacterRange>(2, zone()); 5743a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (has_more() && current() != ']') { 574414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org uc16 char_class = kNoCharClass; 5745a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED); 5746a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == '-') { 5747a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5748a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (current() == kEndMarker) { 5749a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // If we reach the end we break out of the loop and let the 5750a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // following code report an error. 5751a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5752a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else if (current() == ']') { 57537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class, first, zone()); 57547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Singleton('-'), zone()); 5755a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 5756a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 575714a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org uc16 char_class_2 = kNoCharClass; 575814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED); 575914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org if (char_class != kNoCharClass || char_class_2 != kNoCharClass) { 576014a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org // Either end is an escaped character class. Treat the '-' verbatim. 57617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class, first, zone()); 57627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Singleton('-'), zone()); 57637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class_2, next, zone()); 576414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org continue; 5765a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5766a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (first.from() > next.to()) { 5767a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED); 5768a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 57697028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Range(first.from(), next.to()), zone()); 5770a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 57717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org AddRangeOrEscape(ranges, char_class, first, zone()); 5772a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5773a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5774a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!has_more()) { 5775a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return ReportError(CStrVector(kUnterminated) CHECK_FAILED); 5776a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5777a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Advance(); 5778a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (ranges->length() == 0) { 57797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ranges->Add(CharacterRange::Everything(), zone()); 5780a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org is_negated = !is_negated; 5781a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5782c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org return new(zone()) RegExpCharacterClass(ranges, is_negated); 5783a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5784a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5785a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5786a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// ---------------------------------------------------------------------------- 578743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The Parser interface. 578843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 578943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenParserMessage::~ParserMessage() { 579043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < args().length(); i++) 579143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DeleteArray(args()[i]); 579243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DeleteArray(args().start()); 579343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 579443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 579543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 579643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenScriptDataImpl::~ScriptDataImpl() { 57975b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org if (owns_store_) store_.Dispose(); 579843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 579943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 580043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 580143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint ScriptDataImpl::Length() { 58029155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org return store_.length() * sizeof(unsigned); 580343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 580443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 580543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 58069155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgconst char* ScriptDataImpl::Data() { 58079155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org return reinterpret_cast<const char*>(store_.start()); 580843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 580943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 581043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 58110c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgbool ScriptDataImpl::HasError() { 58120c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return has_error(); 58130c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 58140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 58150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 5816d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.comvoid ScriptDataImpl::Initialize() { 5817c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // Prepares state for use. 5818beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (store_.length() >= PreparseDataConstants::kHeaderSize) { 5819beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org function_index_ = PreparseDataConstants::kHeaderSize; 5820beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org int symbol_data_offset = PreparseDataConstants::kHeaderSize 5821beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org + store_[PreparseDataConstants::kFunctionsSizeOffset]; 5822d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (store_.length() > symbol_data_offset) { 5823d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); 5824d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } else { 5825d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Partial preparse causes no symbol information. 5826d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 5827d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } 5828d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 5829d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } 5830d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com} 5831d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 5832d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 5833d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.comint ScriptDataImpl::ReadNumber(byte** source) { 5834d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Reads a number from symbol_data_ in base 128. The most significant 5835d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // bit marks that there are more digits. 5836d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // If the first byte is 0x80 (kNumberTerminator), it would normally 5837d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // represent a leading zero. Since that is useless, and therefore won't 5838d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // appear as the first digit of any actual value, it is used to 5839d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // mark the end of the input stream. 5840d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com byte* data = *source; 5841d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (data >= symbol_data_end_) return -1; 5842d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com byte input = *data; 5843beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (input == PreparseDataConstants::kNumberTerminator) { 5844d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // End of stream marker. 5845d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com return -1; 5846d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } 5847d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com int result = input & 0x7f; 5848d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com data++; 5849d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com while ((input & 0x80u) != 0) { 5850d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (data >= symbol_data_end_) return -1; 5851d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com input = *data; 5852d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com result = (result << 7) | (input & 0x7f); 5853d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com data++; 5854d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com } 5855d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com *source = data; 5856d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com return result; 5857d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com} 5858d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 5859d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 586021b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org// Create a Scanner for the preparser to use as input, and preparse the source. 5861e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgScriptDataImpl* PreParserApi::PreParse(Utf16CharacterStream* source) { 5862e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CompleteParserRecorder recorder; 5863ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate = Isolate::Current(); 58641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org HistogramTimerScope timer(isolate->counters()->pre_parse()); 5865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Scanner scanner(isolate->unicode_cache()); 5866ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org intptr_t stack_limit = isolate->stack_guard()->real_climit(); 5867e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org preparser::PreParser preparser(&scanner, &recorder, stack_limit); 5868e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org preparser.set_allow_lazy(true); 5869e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org preparser.set_allow_generators(FLAG_harmony_generators); 58701fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org preparser.set_allow_for_of(FLAG_harmony_iteration); 5871e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); 5872ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); 5873e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org scanner.Initialize(source); 5874e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org preparser::PreParser::PreParseResult result = preparser.PreParseProgram(); 58751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (result == preparser::PreParser::kPreParseStackOverflow) { 5876ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate->StackOverflow(); 58774a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return NULL; 58784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com } 58794a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 58804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Extract the accumulated data from the recorder as a single 58814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // contiguous vector that we are responsible for disposing. 5882e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Vector<unsigned> store = recorder.ExtractData(); 58834a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return new ScriptDataImpl(store); 58844a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 58854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 58864a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 5887e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgbool RegExpParser::ParseRegExp(FlatStringReader* input, 5888e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org bool multiline, 58895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org RegExpCompileData* result, 58905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Zone* zone) { 5891a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(result != NULL); 58925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org RegExpParser parser(input, &result->error, multiline, zone); 589337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com RegExpTree* tree = parser.ParsePattern(); 5894a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (parser.failed()) { 589537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com ASSERT(tree == NULL); 5896a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(!result->error.is_null()); 5897a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 589837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com ASSERT(tree != NULL); 5899a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(result->error.is_null()); 590037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result->tree = tree; 590137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com int capture_count = parser.captures_started(); 590237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; 5903245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org result->contains_anchor = parser.contains_anchor(); 590437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result->capture_count = capture_count; 5905a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 5906a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return !parser.failed(); 5907a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 5908a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5909a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5910e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool Parser::Parse() { 5911e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(info()->function() == NULL); 5912b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org FunctionLiteral* result = NULL; 5913e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (info()->is_lazy()) { 5914e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!info()->is_eval()); 5915e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (info()->shared_info()->is_function()) { 5916e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org result = ParseLazy(); 591756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org } else { 5918e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org result = ParseProgram(); 591956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org } 5920b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 5921e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); 5922e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org set_pre_parse_data(pre_parse_data); 5923e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (pre_parse_data != NULL && pre_parse_data->has_error()) { 5924e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Scanner::Location loc = pre_parse_data->MessageLocation(); 5925e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const char* message = pre_parse_data->BuildMessage(); 5926e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Vector<const char*> args = pre_parse_data->BuildArgs(); 5927e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ReportMessageAt(loc, message, args); 5928b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org DeleteArray(message); 5929b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org for (int i = 0; i < args.length(); i++) { 5930b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org DeleteArray(args[i]); 5931b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org } 5932b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org DeleteArray(args.start()); 5933e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(info()->isolate()->has_pending_exception()); 5934b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org } else { 5935e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org result = ParseProgram(); 5936b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org } 5937b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 5938e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org info()->SetFunction(result); 5939b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org return (result != NULL); 594043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 594143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 594243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 5943