13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "api.h" 313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "ast.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "bootstrapper.h" 33589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "char-predicates-inl.h" 346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "codegen.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "compiler.h" 3680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "func-name-inferrer.h" 376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "messages.h" 3825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen#include "parser.h" 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "platform.h" 403e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu#include "preparser.h" 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "runtime.h" 42589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "scanner-character-streams.h" 433bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch#include "scopeinfo.h" 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "string-stream.h" 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PositionStack is used for on-stack allocation of token positions for 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// new expressions. Please look at ParseNewExpression. 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass PositionStack { 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {} 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~PositionStack() { ASSERT(!*ok_ || is_empty()); } 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class Element { 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Element(PositionStack* stack, int value) { 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block previous_ = stack->top(); 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value_ = value; 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stack->set_top(this); 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Element* previous() { return previous_; } 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int value() { return value_; } 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class PositionStack; 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Element* previous_; 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int value_; 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_empty() { return top_ == NULL; } 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pop() { 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!is_empty()); 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int result = top_->value(); 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block top_ = top_->previous(); 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Element* top() { return top_; } 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_top(Element* value) { top_ = value; } 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Element* top_; 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* ok_; 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpBuilder::RegExpBuilder() 908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : zone_(Isolate::Current()->zone()), 918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch pending_empty_(false), 928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch characters_(NULL), 938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch terms_(), 948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch alternatives_() 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch , last_added_(ADD_NONE) 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {} 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpBuilder::FlushCharacters() { 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pending_empty_ = false; 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (characters_ != NULL) { 1048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector()); 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block characters_ = NULL; 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block text_.Add(atom); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LAST(ADD_ATOM); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpBuilder::FlushText() { 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FlushCharacters(); 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int num_text = text_.length(); 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (num_text == 0) { 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (num_text == 1) { 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block terms_.Add(text_.last()); 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RegExpText* text = new(zone()) RegExpText(); 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < num_text; i++) 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block text_.Get(i)->AppendToText(text); 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block terms_.Add(text); 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block text_.Clear(); 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpBuilder::AddCharacter(uc16 c) { 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pending_empty_ = false; 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (characters_ == NULL) { 132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch characters_ = new(zone()) ZoneList<uc16>(4); 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block characters_->Add(c); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LAST(ADD_CHAR); 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpBuilder::AddEmpty() { 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pending_empty_ = true; 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpBuilder::AddAtom(RegExpTree* term) { 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (term->IsEmpty()) { 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddEmpty(); 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (term->IsTextElement()) { 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FlushCharacters(); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block text_.Add(term); 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FlushText(); 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block terms_.Add(term); 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LAST(ADD_ATOM); 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpBuilder::AddAssertion(RegExpTree* assert) { 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FlushText(); 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block terms_.Add(assert); 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LAST(ADD_ASSERT); 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpBuilder::NewAlternative() { 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FlushTerms(); 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpBuilder::FlushTerms() { 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FlushText(); 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int num_terms = terms_.length(); 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpTree* alternative; 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (num_terms == 0) { 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block alternative = RegExpEmpty::GetInstance(); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (num_terms == 1) { 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block alternative = terms_.last(); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch alternative = new(zone()) RegExpAlternative(terms_.GetList()); 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block alternatives_.Add(alternative); 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block terms_.Clear(); 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LAST(ADD_NONE); 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpTree* RegExpBuilder::ToRegExp() { 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FlushTerms(); 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int num_alternatives = alternatives_.length(); 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (num_alternatives == 0) { 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return RegExpEmpty::GetInstance(); 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (num_alternatives == 1) { 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return alternatives_.last(); 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return new(zone()) RegExpDisjunction(alternatives_.GetList()); 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 202e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid RegExpBuilder::AddQuantifierToAtom(int min, 203e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int max, 204e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke RegExpQuantifier::Type type) { 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (pending_empty_) { 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pending_empty_ = false; 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpTree* atom; 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (characters_ != NULL) { 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(last_added_ == ADD_CHAR); 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Last atom was character. 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<const uc16> char_vector = characters_->ToConstVector(); 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int num_chars = char_vector.length(); 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (num_chars > 1) { 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1); 2178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch text_.Add(new(zone()) RegExpAtom(prefix)); 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char_vector = char_vector.SubVector(num_chars - 1, num_chars); 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block characters_ = NULL; 2218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch atom = new(zone()) RegExpAtom(char_vector); 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FlushText(); 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (text_.length() > 0) { 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(last_added_ == ADD_ATOM); 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block atom = text_.RemoveLast(); 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FlushText(); 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (terms_.length() > 0) { 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(last_added_ == ADD_ATOM); 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block atom = terms_.RemoveLast(); 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (atom->max_match() == 0) { 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Guaranteed to only match an empty string. 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LAST(ADD_TERM); 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (min == 0) { 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block terms_.Add(atom); 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Only call immediately after adding an atom or character! 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNREACHABLE(); 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch terms_.Add(new(zone()) RegExpQuantifier(min, max, type, atom)); 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LAST(ADD_TERM); 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2499fac840a46e8b7e26894f4792ba26dde14c56b04Steve BlockHandle<String> Parser::LookupSymbol(int symbol_id) { 2503e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Length of symbol cache is the number of identified symbols. 2513e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // If we are larger than that, or negative, it's not a cached symbol. 2523e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // This might also happen if there is no preparser symbol data, even 2533e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // if there is some preparser data. 2543e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (static_cast<unsigned>(symbol_id) 2553e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu >= static_cast<unsigned>(symbol_cache_.length())) { 2569fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block if (scanner().is_literal_ascii()) { 25744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->factory()->LookupAsciiSymbol( 25844f0eee88ff00398ff7f715fab053374d808c90dSteve Block scanner().literal_ascii_string()); 2599fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block } else { 26044f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->factory()->LookupTwoByteSymbol( 2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scanner().literal_utf16_string()); 2629fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block } 2633e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu } 2649fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block return LookupCachedSymbol(symbol_id); 2653e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu} 2663e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 2673e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 2689fac840a46e8b7e26894f4792ba26dde14c56b04Steve BlockHandle<String> Parser::LookupCachedSymbol(int symbol_id) { 2693e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Make sure the cache is large enough to hold the symbol identifier. 2703e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (symbol_cache_.length() <= symbol_id) { 2713e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Increase length to index + 1. 2723e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu symbol_cache_.AddBlock(Handle<String>::null(), 2733e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu symbol_id + 1 - symbol_cache_.length()); 2743e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu } 2753e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Handle<String> result = symbol_cache_.at(symbol_id); 2763e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (result.is_null()) { 2779fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block if (scanner().is_literal_ascii()) { 27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block result = isolate()->factory()->LookupAsciiSymbol( 27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block scanner().literal_ascii_string()); 2809fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block } else { 28144f0eee88ff00398ff7f715fab053374d808c90dSteve Block result = isolate()->factory()->LookupTwoByteSymbol( 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scanner().literal_utf16_string()); 2839fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block } 2843e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu symbol_cache_.at(symbol_id) = result; 2859ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick return result; 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 28744f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->counters()->total_preparse_symbols_skipped()->Increment(); 2883e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu return result; 2893e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu} 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenFunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { 29380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // The current pre-data entry must be a FunctionEntry with the given 29480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // start position. 2959ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick if ((function_index_ + FunctionEntry::kSize <= store_.length()) 2969ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick && (static_cast<int>(store_[function_index_]) == start)) { 2979ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick int index = function_index_; 2989ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick function_index_ += FunctionEntry::kSize; 29980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return FunctionEntry(store_.SubVector(index, 30080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index + FunctionEntry::kSize)); 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return FunctionEntry(); 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3060d5e116f6aee03185f237311a943491bb079a768Kristian Monsenint ScriptDataImpl::GetSymbolIdentifier() { 3070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return ReadNumber(&symbol_data_); 3089ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick} 3099ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick 3109ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick 3119ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrickbool ScriptDataImpl::SanityCheck() { 3129ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick // Check that the header data is valid and doesn't specify 3139ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick // point to positions outside the store. 3148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (store_.length() < PreparseDataConstants::kHeaderSize) return false; 3158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (magic() != PreparseDataConstants::kMagicNumber) return false; 3168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (version() != PreparseDataConstants::kCurrentVersion) return false; 3179ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick if (has_error()) { 3189ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick // Extra sane sanity check for error message encoding. 3198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (store_.length() <= PreparseDataConstants::kHeaderSize 3208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang + PreparseDataConstants::kMessageTextPos) { 3218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return false; 3228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 3238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (Read(PreparseDataConstants::kMessageStartPos) > 3248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Read(PreparseDataConstants::kMessageEndPos)) { 3258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return false; 3268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 3278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos); 3288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int pos = PreparseDataConstants::kMessageTextPos; 3299ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick for (unsigned int i = 0; i <= arg_count; i++) { 3308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) { 3318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return false; 3328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 3339ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick int length = static_cast<int>(Read(pos)); 3349ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick if (length < 0) return false; 3359ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick pos += 1 + length; 3369ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick } 3378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (store_.length() < PreparseDataConstants::kHeaderSize + pos) { 3388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return false; 3398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 3409ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick return true; 3419ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick } 3429ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick // Check that the space allocated for function entries is sane. 3439ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick int functions_size = 3448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]); 3459ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick if (functions_size < 0) return false; 3469ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick if (functions_size % FunctionEntry::kSize != 0) return false; 3479ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick // Check that the count of symbols is non-negative. 3489ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick int symbol_count = 3498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang static_cast<int>(store_[PreparseDataConstants::kSymbolCountOffset]); 3509ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick if (symbol_count < 0) return false; 3510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Check that the total size has room for header and function entries. 3529ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick int minimum_size = 3538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang PreparseDataConstants::kHeaderSize + functions_size; 3549ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick if (store_.length() < minimum_size) return false; 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35959151504615d929945dc59db37bf1166937748c6Steve Block 36080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenconst char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int length = start[0]; 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* result = NewArray<char>(length + 1); 36380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen for (int i = 0; i < length; i++) { 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result[i] = start[i + 1]; 36580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result[length] = '\0'; 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (chars != NULL) *chars = length; 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockScanner::Location ScriptDataImpl::MessageLocation() { 3728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int beg_pos = Read(PreparseDataConstants::kMessageStartPos); 3738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int end_pos = Read(PreparseDataConstants::kMessageEndPos); 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Scanner::Location(beg_pos, end_pos); 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* ScriptDataImpl::BuildMessage() { 3798a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos); 38080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return ReadString(start, NULL); 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockVector<const char*> ScriptDataImpl::BuildArgs() { 3858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int arg_count = Read(PreparseDataConstants::kMessageArgCountPos); 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char** array = NewArray<const char*>(arg_count); 3870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Position after text found by skipping past length field and 3880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // length field content words. 3898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int pos = PreparseDataConstants::kMessageTextPos + 1 3908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang + Read(PreparseDataConstants::kMessageTextPos); 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < arg_count; i++) { 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int count = 0; 39380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen array[i] = ReadString(ReadAddress(pos), &count); 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos += count + 1; 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Vector<const char*>(array, arg_count); 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockunsigned ScriptDataImpl::Read(int position) { 4018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return store_[PreparseDataConstants::kHeaderSize + position]; 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockunsigned* ScriptDataImpl::ReadAddress(int position) { 4068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return &store_[PreparseDataConstants::kHeaderSize + position]; 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochScope* Parser::NewScope(Scope* parent, ScopeType type) { 4118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Scope* result = new(zone()) Scope(parent, type); 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result->Initialize(); 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Target is a support class to facilitate manipulation of the 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Parser's target_stack_ (the stack of potential 'break' and 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 'continue' statement targets). Upon construction, a new target is 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// added; it is removed upon destruction. 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Target BASE_EMBEDDED { 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 4253e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Target(Target** variable, AstNode* node) 4263e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu : variable_(variable), node_(node), previous_(*variable) { 4273e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu *variable = this; 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~Target() { 4313e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu *variable_ = previous_; 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Target* previous() { return previous_; } 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AstNode* node() { return node_; } 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 4383e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Target** variable_; 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AstNode* node_; 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Target* previous_; 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TargetScope BASE_EMBEDDED { 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 4463e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu explicit TargetScope(Target** variable) 4473e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu : variable_(variable), previous_(*variable) { 4483e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu *variable = NULL; 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~TargetScope() { 4523e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu *variable_ = previous_; 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 4563e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Target** variable_; 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Target* previous_; 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// FunctionState and BlockState together implement the parser's scope stack. 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The parser's current scope is in top_scope_. The BlockState and 4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// FunctionState constructors push on the scope stack and the destructors 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// pop. They are also used to hold the parser's per-function and per-block 4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// state. 467592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass Parser::BlockState BASE_EMBEDDED { 469592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch public: 4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BlockState(Parser* parser, Scope* scope) 4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : parser_(parser), 4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outer_scope_(parser->top_scope_) { 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parser->top_scope_ = scope; 474592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 475592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 4763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ~BlockState() { parser_->top_scope_ = outer_scope_; } 477592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 478592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch private: 479592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Parser* parser_; 4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* outer_scope_; 481592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}; 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochParser::FunctionState::FunctionState(Parser* parser, 4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* scope, 4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Isolate* isolate) 4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), 4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch next_handler_index_(0), 4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expected_property_count_(0), 4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch only_simple_this_property_assignments_(false), 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch this_property_assignments_(isolate->factory()->empty_fixed_array()), 4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parser_(parser), 4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outer_function_state_(parser->current_function_state_), 4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outer_scope_(parser->top_scope_), 4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch saved_ast_node_id_(isolate->ast_node_id()), 4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory_(isolate) { 49744f0eee88ff00398ff7f715fab053374d808c90dSteve Block parser->top_scope_ = scope; 4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parser->current_function_state_ = this; 499589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch isolate->set_ast_node_id(AstNode::kDeclarationsId + 1); 50044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 50144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 50244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochParser::FunctionState::~FunctionState() { 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parser_->top_scope_ = outer_scope_; 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parser_->current_function_state_ = outer_function_state_; 5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (outer_function_state_ != NULL) { 5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parser_->isolate()->set_ast_node_id(saved_ast_node_id_); 5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 50944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 51044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 51144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The CHECK_OK macro is a convenient macro to enforce error 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// handling for functions that may fail (by returning !*ok). 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CAUTION: This macro appends extra statements after a call, 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// thus it must never be used where only a single statement 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// is correct (e.g. an if statement branch w/o braces)! 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHECK_OK ok); \ 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!*ok) return NULL; \ 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ((void)0 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DUMMY ) // to make indentation work 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DUMMY 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHECK_FAILED /**/); \ 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (failed_) return NULL; \ 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ((void)0 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DUMMY ) // to make indentation work 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DUMMY 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of Parser 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockParser::Parser(Handle<Script> script, 5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int parser_flags, 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Extension* extension, 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScriptDataImpl* pre_data) 53944f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(script->GetIsolate()), 54044f0eee88ff00398ff7f715fab053374d808c90dSteve Block symbol_cache_(pre_data ? pre_data->symbol_count() : 0), 5413e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu script_(script), 5428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch scanner_(isolate_->unicode_cache()), 5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reusable_preparser_(NULL), 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block top_scope_(NULL), 5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current_function_state_(NULL), 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block target_stack_(NULL), 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block extension_(extension), 5486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block pre_data_(pre_data), 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch fni_(NULL), 5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch allow_natives_syntax_((parser_flags & kAllowNativesSyntax) != 0), 5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch allow_lazy_((parser_flags & kAllowLazy) != 0), 5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch allow_modules_((parser_flags & kAllowModules) != 0), 553b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch stack_overflow_(false), 5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parenthesized_function_(false) { 5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->set_ast_node_id(0); 5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) { 5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scanner().SetHarmonyScoping(true); 5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((parser_flags & kAllowModules) != 0) { 5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scanner().SetHarmonyModules(true); 5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochFunctionLiteral* Parser::ParseProgram(CompilationInfo* info) { 5663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56844f0eee88ff00398ff7f715fab053374d808c90dSteve Block HistogramTimerScope timer(isolate()->counters()->parse()); 5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> source(String::cast(script_->source())); 57044f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->counters()->total_parse_size()->Increment(source->length()); 5713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fni_ = new(zone()) FuncNameInferrer(isolate()); 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Initialize parser state. 5746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block source->TryFlatten(); 575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (source->IsExternalTwoByteString()) { 576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Notice that the stream is destroyed at the end of the branch block. 577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The last line of the blocks can't be moved outside, even though they're 578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // identical calls. 5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalTwoByteStringUtf16CharacterStream stream( 580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 5819fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block scanner_.Initialize(&stream); 5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return DoParseProgram(info, source, &zone_scope); 583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GenericStringUtf16CharacterStream stream(source, 0, source->length()); 5859fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block scanner_.Initialize(&stream); 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return DoParseProgram(info, source, &zone_scope); 587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochFunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, 5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> source, 593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneScope* zone_scope) { 5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(top_scope_ == NULL); 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(target_stack_ == NULL); 5960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (pre_data_ != NULL) pre_data_->Initialize(); 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the parsing mode. 5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mode_ = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY; 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 60244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> no_name = isolate()->factory()->empty_symbol(); 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionLiteral* result = NULL; 6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->SetGlobalScope(scope); 6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (info->is_eval()) { 6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<SharedFunctionInfo> shared = info->shared_info(); 6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!info->is_global() && (shared.is_null() || shared->is_function())) { 6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope = Scope::DeserializeScopeChain(*info->calling_context(), scope); 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { 6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope = NewScope(scope, EVAL_SCOPE); 6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->set_start_position(0); 6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->set_end_position(source->length()); 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionState function_state(this, scope, isolate()); 6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_->SetLanguageMode(info->language_mode()); 620257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool ok = true; 6221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int beg_loc = scanner().location().beg_pos; 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ParseSourceElements(body, Token::EOS, info->is_eval(), &ok); 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (ok && !top_scope_->is_classic_mode()) { 6251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); 6261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 627589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (ok && is_extended_mode()) { 6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckConflictingVarDeclarations(top_scope_, &ok); 630589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 631589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ok) { 6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewFunctionLiteral( 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block no_name, 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block top_scope_, 6363e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu body, 6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_state.materialized_literal_count(), 6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_state.expected_property_count(), 6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_state.handler_count(), 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_state.only_simple_this_property_assignments(), 6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_state.this_property_assignments(), 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionLiteral::kNoDuplicateParameters, 6443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch FunctionLiteral::ANONYMOUS_EXPRESSION, 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionLiteral::kGlobalOrEval); 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result->set_ast_properties(factory()->visitor()->ast_properties()); 647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (stack_overflow_) { 64844f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->StackOverflow(); 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure the target stack is empty. 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(target_stack_ == NULL); 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there was a syntax error we have to get rid of the AST 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and it is not safe to do so before the scope has been deleted. 657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (result == NULL) zone_scope->DeleteOnExit(); 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 66244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockFunctionLiteral* Parser::ParseLazy(CompilationInfo* info) { 6633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); 66444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HistogramTimerScope timer(isolate()->counters()->parse_lazy()); 665f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<String> source(String::cast(script_->source())); 66644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->counters()->total_parse_size()->Increment(source->length()); 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 66844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<SharedFunctionInfo> shared_info = info->shared_info(); 669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Initialize parser state. 670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch source->TryFlatten(); 671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (source->IsExternalTwoByteString()) { 6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalTwoByteStringUtf16CharacterStream stream( 673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<ExternalTwoByteString>::cast(source), 67444f0eee88ff00398ff7f715fab053374d808c90dSteve Block shared_info->start_position(), 67544f0eee88ff00398ff7f715fab053374d808c90dSteve Block shared_info->end_position()); 676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); 677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return result; 678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GenericStringUtf16CharacterStream stream(source, 6803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shared_info->start_position(), 6813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shared_info->end_position()); 682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); 683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return result; 684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 68844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockFunctionLiteral* Parser::ParseLazy(CompilationInfo* info, 6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Utf16CharacterStream* source, 690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneScope* zone_scope) { 69144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<SharedFunctionInfo> shared_info = info->shared_info(); 6929fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block scanner_.Initialize(source); 6933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(top_scope_ == NULL); 694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(target_stack_ == NULL); 695b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 69644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> name(String::cast(shared_info->name())); 6973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fni_ = new(zone()) FuncNameInferrer(isolate()); 69880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen fni_->PushEnclosingName(name); 69980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block mode_ = PARSE_EAGERLY; 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Place holder for the result. 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionLiteral* result = NULL; 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parse the function literal. 7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->SetGlobalScope(scope); 70944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!info->closure().is_null()) { 7103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope = Scope::DeserializeScopeChain(info->closure()->context(), scope); 7111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 7123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionState function_state(this, scope, isolate()); 7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(scope->language_mode() != STRICT_MODE || !info->is_classic_mode()); 7143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(scope->language_mode() != EXTENDED_MODE || 7153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->is_extended_mode()); 7163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(info->language_mode() == shared_info->language_mode()); 7173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->SetLanguageMode(shared_info->language_mode()); 7183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch FunctionLiteral::Type type = shared_info->is_expression() 7193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ? (shared_info->is_anonymous() 7203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ? FunctionLiteral::ANONYMOUS_EXPRESSION 7213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : FunctionLiteral::NAMED_EXPRESSION) 7223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : FunctionLiteral::DECLARATION; 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool ok = true; 7241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block result = ParseFunctionLiteral(name, 7253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch false, // Strict mode name already checked. 7263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch RelocInfo::kNoPosition, 7273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch type, 7283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch &ok); 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure the results agree. 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(ok == (result != NULL)); 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure the target stack is empty. 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(target_stack_ == NULL); 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there was a stack overflow we have to get rid of AST and it is 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // not safe to do before scope has been deleted. 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result == NULL) { 739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch zone_scope->DeleteOnExit(); 74044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (stack_overflow_) isolate()->StackOverflow(); 741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 74244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> inferred_name(shared_info->inferred_name()); 743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result->set_inferred_name(inferred_name); 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 748f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 7493e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui ZhuHandle<String> Parser::GetSymbol(bool* ok) { 7503e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu int symbol_id = -1; 7513e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (pre_data() != NULL) { 7523e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu symbol_id = pre_data()->GetSymbolIdentifier(); 7534515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 7549fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block return LookupSymbol(symbol_id); 7554515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7573e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Parser::ReportMessage(const char* type, Vector<const char*> args) { 759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Scanner::Location source_location = scanner().location(); 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportMessageAt(source_location, type, args); 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Parser::ReportMessage(const char* type, Vector<Handle<String> > args) { 7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scanner::Location source_location = scanner().location(); 7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReportMessageAt(source_location, type, args); 7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7703e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhuvoid Parser::ReportMessageAt(Scanner::Location source_location, 7713e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu const char* type, 7723e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Vector<const char*> args) { 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageLocation location(script_, 774b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch source_location.beg_pos, 775b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch source_location.end_pos); 77644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Factory* factory = isolate()->factory(); 77744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<FixedArray> elements = factory->NewFixedArray(args.length()); 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < args.length(); i++) { 77944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); 780e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch elements->set(i, *arg_string); 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 78244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSArray> array = factory->NewJSArrayWithElements(elements); 78344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> result = factory->NewSyntaxError(type, array); 78444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->Throw(*result, &location); 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 788b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid Parser::ReportMessageAt(Scanner::Location source_location, 789b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const char* type, 790b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Vector<Handle<String> > args) { 791b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch MessageLocation location(script_, 792b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch source_location.beg_pos, 793b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch source_location.end_pos); 79444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Factory* factory = isolate()->factory(); 79544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<FixedArray> elements = factory->NewFixedArray(args.length()); 796b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch for (int i = 0; i < args.length(); i++) { 797e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch elements->set(i, *args[i]); 798b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 79944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSArray> array = factory->NewJSArrayWithElements(elements); 80044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> result = factory->NewSyntaxError(type, array); 80144f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->Throw(*result, &location); 802b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 803b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 804b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Base class containing common code for the different finder classes used by 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the parser. 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ParserFinder { 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ParserFinder() {} 810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Assignment* AsAssignment(Statement* stat) { 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (stat == NULL) return NULL; 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpressionStatement* exp_stat = stat->AsExpressionStatement(); 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (exp_stat == NULL) return NULL; 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return exp_stat->expression()->AsAssignment(); 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An InitializationBlockFinder finds and marks sequences of statements of the 820d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// form expr.a = ...; expr.b = ...; etc. 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass InitializationBlockFinder : public ParserFinder { 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 8233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We find and mark the initialization blocks in top level 8243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // non-looping code only. This is because the optimization prevents 8253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // reuse of the map transitions, so it should be used only for code 8263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // that will only be run once. 8273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch InitializationBlockFinder(Scope* top_scope, Target* target) 8283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : enabled_(top_scope->DeclarationScope()->is_global_scope() && 8293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch !IsLoopTarget(target)), 8303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch first_in_block_(NULL), 8313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch last_in_block_(NULL), 8323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch block_size_(0) {} 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~InitializationBlockFinder() { 8353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!enabled_) return; 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (InBlock()) EndBlock(); 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Update(Statement* stat) { 8403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!enabled_) return; 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assignment* assignment = AsAssignment(stat); 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (InBlock()) { 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (BlockContinues(assignment)) { 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UpdateBlock(assignment); 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EndBlock(); 847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!InBlock() && (assignment != NULL) && 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (assignment->op() == Token::ASSIGN)) { 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StartBlock(assignment); 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 8563e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // The minimum number of contiguous assignment that will 8573e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // be treated as an initialization block. Benchmarks show that 8583e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // the overhead exceeds the savings below this limit. 8593e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu static const int kMinInitializationBlock = 3; 8603e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 8613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static bool IsLoopTarget(Target* target) { 8623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (target != NULL) { 8633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (target->node()->AsIterationStatement() != NULL) return true; 8643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch target = target->previous(); 8653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return false; 8673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns true if the expressions appear to denote the same object. 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // In the context of initialization blocks, we only consider expressions 871d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // of the form 'expr.x' or expr["x"]. 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool SameObject(Expression* e1, Expression* e2) { 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VariableProxy* v1 = e1->AsVariableProxy(); 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VariableProxy* v2 = e2->AsVariableProxy(); 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (v1 != NULL && v2 != NULL) { 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v1->name()->Equals(*v2->name()); 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Property* p1 = e1->AsProperty(); 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Property* p2 = e2->AsProperty(); 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((p1 == NULL) || (p2 == NULL)) return false; 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Literal* key1 = p1->key()->AsLiteral(); 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Literal* key2 = p2->key()->AsLiteral(); 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((key1 == NULL) || (key2 == NULL)) return false; 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!key1->handle()->IsString() || !key2->handle()->IsString()) { 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name1 = String::cast(*key1->handle()); 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name2 = String::cast(*key2->handle()); 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!name1->Equals(name2)) return false; 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return SameObject(p1->obj(), p2->obj()); 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns true if the expressions appear to denote different properties 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // of the same object. 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool PropertyOfSameObject(Expression* e1, Expression* e2) { 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Property* p1 = e1->AsProperty(); 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Property* p2 = e2->AsProperty(); 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((p1 == NULL) || (p2 == NULL)) return false; 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return SameObject(p1->obj(), p2->obj()); 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool BlockContinues(Assignment* assignment) { 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((assignment == NULL) || (first_in_block_ == NULL)) return false; 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (assignment->op() != Token::ASSIGN) return false; 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return PropertyOfSameObject(first_in_block_->target(), 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assignment->target()); 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void StartBlock(Assignment* assignment) { 910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block first_in_block_ = assignment; 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_in_block_ = assignment; 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block block_size_ = 1; 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateBlock(Assignment* assignment) { 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_in_block_ = assignment; 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ++block_size_; 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void EndBlock() { 9213e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (block_size_ >= kMinInitializationBlock) { 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block first_in_block_->mark_block_start(); 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_in_block_->mark_block_end(); 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_in_block_ = first_in_block_ = NULL; 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block block_size_ = 0; 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool InBlock() { return first_in_block_ != NULL; } 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const bool enabled_; 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assignment* first_in_block_; 933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assignment* last_in_block_; 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int block_size_; 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder); 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// A ThisNamedPropertyAssignmentFinder finds and marks statements of the form 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this.x = ...;, where x is a named property. It also determines whether a 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function contains only assignments of this type. 9433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass ThisNamedPropertyAssignmentFinder : public ParserFinder { 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 9453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ThisNamedPropertyAssignmentFinder(Isolate* isolate) 94644f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(isolate), 94744f0eee88ff00398ff7f715fab053374d808c90dSteve Block only_simple_this_property_assignments_(true), 9483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch names_(0), 9493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_arguments_(0), 9503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_constants_(0) { 9513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Update(Scope* scope, Statement* stat) { 954d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Bail out if function already has property assignment that are 955d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // not simple this property assignments. 956d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!only_simple_this_property_assignments_) { 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check whether this statement is of the form this.x = ...; 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assignment* assignment = AsAssignment(stat); 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsThisPropertyAssignment(assignment)) { 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleThisPropertyAssignment(scope, assignment); 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block only_simple_this_property_assignments_ = false; 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns whether only statements of the form this.x = y; where y is either a 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // constant or a function argument was encountered. 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool only_simple_this_property_assignments() { 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return only_simple_this_property_assignments_; 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns a fixed array containing three elements for each assignment of the 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // form this.x = y; 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> GetThisPropertyAssignments() { 9783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (names_.is_empty()) { 97944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate_->factory()->empty_fixed_array(); 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 9813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(names_.length(), assigned_arguments_.length()); 9823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(names_.length(), assigned_constants_.length()); 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> assignments = 9843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->factory()->NewFixedArray(names_.length() * 3); 9853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < names_.length(); ++i) { 9863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assignments->set(i * 3, *names_[i]); 9873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_[i])); 9883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assignments->set(i * 3 + 2, *assigned_constants_[i]); 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return assignments; 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsThisPropertyAssignment(Assignment* assignment) { 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (assignment != NULL) { 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Property* property = assignment->target()->AsProperty(); 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return assignment->op() == Token::ASSIGN 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block && property != NULL 999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block && property->obj()->AsVariableProxy() != NULL 1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block && property->obj()->AsVariableProxy()->is_this(); 1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) { 10066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Check that the property assigned to is a named property, which is not 10076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // __proto__. 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Property* property = assignment->target()->AsProperty(); 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(property != NULL); 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Literal* literal = property->key()->AsLiteral(); 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t dummy; 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (literal != NULL && 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block literal->handle()->IsString() && 101444f0eee88ff00398ff7f715fab053374d808c90dSteve Block !String::cast(*(literal->handle()))->Equals( 101544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->Proto_symbol()) && 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) { 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> key = Handle<String>::cast(literal->handle()); 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check whether the value assigned is either a constant or matches the 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // name of one of the arguments to the function. 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (assignment->value()->AsLiteral() != NULL) { 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Constant assigned. 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Literal* literal = assignment->value()->AsLiteral(); 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AssignmentFromConstant(key, literal->handle()); 1025d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return; 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (assignment->value()->AsVariableProxy() != NULL) { 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Variable assigned. 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name = 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assignment->value()->AsVariableProxy()->name(); 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check whether the variable assigned matches an argument name. 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < scope->num_parameters(); i++) { 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*scope->parameter(i)->name() == *name) { 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Assigned from function argument. 1034d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block AssignmentFromParameter(key, i); 1035d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return; 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1040d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // It is not a simple "this.x = value;" assignment with a constant 1041d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // or parameter value. 1042d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block AssignmentFromSomethingElse(); 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We will potentially reorder the property assignments, so they must be 10493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // simple enough that the ordering does not matter. 1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AssignmentFromParameter(Handle<String> name, int index) { 10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EnsureInitialized(); 10523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < names_.length(); ++i) { 10533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (name->Equals(*names_[i])) { 10543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_arguments_[i] = index; 10553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_constants_[i] = isolate_->factory()->undefined_value(); 10563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 10573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch names_.Add(name); 10603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_arguments_.Add(index); 10613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_constants_.Add(isolate_->factory()->undefined_value()); 1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AssignmentFromConstant(Handle<String> name, Handle<Object> value) { 10653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EnsureInitialized(); 10663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < names_.length(); ++i) { 10673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (name->Equals(*names_[i])) { 10683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_arguments_[i] = -1; 10693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_constants_[i] = value; 10703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 10713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch names_.Add(name); 10743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_arguments_.Add(-1); 10753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_constants_.Add(value); 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1078d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void AssignmentFromSomethingElse() { 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The this assignment is not a simple one. 1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block only_simple_this_property_assignments_ = false; 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void EnsureInitialized() { 10843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (names_.capacity() == 0) { 10853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(assigned_arguments_.capacity() == 0); 10863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(assigned_constants_.capacity() == 0); 10873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch names_.Initialize(4); 10883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_arguments_.Initialize(4); 10893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assigned_constants_.Initialize(4); 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool only_simple_this_property_assignments_; 10953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ZoneStringList names_; 10963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ZoneList<int> assigned_arguments_; 10973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ZoneObjectList assigned_constants_; 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11013e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhuvoid* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int end_token, 11033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool is_eval, 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* ok) { 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // SourceElements :: 11063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // (ModuleElement)* <end_token> 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate a target stack to use for this set of source 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // elements. This way, all scripts and functions get their own 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // target stack thus avoiding illegal breaks and continues across 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // functions. 11123e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu TargetScope scope(&this->target_stack_); 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(processor != NULL); 11153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch InitializationBlockFinder block_finder(top_scope_, target_stack_); 11163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate()); 11171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool directive_prologue = true; // Parsing directive prologue. 11181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (peek() != end_token) { 11201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (directive_prologue && peek() != Token::STRING) { 11211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block directive_prologue = false; 11221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 11231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 11241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Scanner::Location token_loc = scanner().peek_location(); 11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Statement* stat = ParseModuleElement(NULL, CHECK_OK); 11261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (stat == NULL || stat->IsEmpty()) { 11271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block directive_prologue = false; // End of directive prologue. 11281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block continue; 11291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 11301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 11311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (directive_prologue) { 11321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // A shot at a directive. 11333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpressionStatement* e_stat; 11343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Literal* literal; 11351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Still processing directive prologue? 11361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if ((e_stat = stat->AsExpressionStatement()) != NULL && 11371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block (literal = e_stat->expression()->AsLiteral()) != NULL && 11381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block literal->handle()->IsString()) { 11391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Handle<String> directive = Handle<String>::cast(literal->handle()); 11401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 11411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Check "use strict" directive (ES5 14.1). 11423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (top_scope_->is_classic_mode() && 114344f0eee88ff00398ff7f715fab053374d808c90dSteve Block directive->Equals(isolate()->heap()->use_strict()) && 11441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block token_loc.end_pos - token_loc.beg_pos == 114544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->heap()->use_strict()->length() + 2) { 11463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(mstarzinger): Global strict eval calls, need their own scope 11473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // as specified in ES5 10.4.2(3). The correct fix would be to always 11483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // add this scope in DoParseProgram(), but that requires adaptations 11493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // all over the code base, so we go with a quick-fix for now. 11503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (is_eval && !top_scope_->is_eval_scope()) { 11513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(top_scope_->is_global_scope()); 11523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* scope = NewScope(top_scope_, EVAL_SCOPE); 11533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->set_start_position(top_scope_->start_position()); 11543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->set_end_position(top_scope_->end_position()); 11553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_ = scope; 11563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(ES6): Fix entering extended mode, once it is specified. 11583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_->SetLanguageMode(FLAG_harmony_scoping 11593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? EXTENDED_MODE : STRICT_MODE); 11601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // "use strict" is the only directive for now. 11611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block directive_prologue = false; 11621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 11631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 11641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // End of the directive prologue. 11651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block directive_prologue = false; 11661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 11671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 11681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 11693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch block_finder.Update(stat); 1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find and mark all assignments to named properties in this (this.x =) 1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (top_scope_->is_function_scope()) { 1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this_property_assignment_finder.Update(top_scope_, stat); 1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block processor->Add(stat); 1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Propagate the collected information on this property assignments. 11783e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (top_scope_->is_function_scope()) { 1179d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block bool only_simple_this_property_assignments = 1180402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu this_property_assignment_finder.only_simple_this_property_assignments() 1181402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu && top_scope_->declarations()->length() == 0; 1182d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (only_simple_this_property_assignments) { 11833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current_function_state_->SetThisPropertyAssignmentInfo( 1184d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block only_simple_this_property_assignments, 1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this_property_assignment_finder.GetThisPropertyAssignments()); 1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 11883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0; 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11933ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochStatement* Parser::ParseModuleElement(ZoneStringList* labels, 11943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool* ok) { 11953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // (Ecma 262 5th Edition, clause 14): 11963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // SourceElement: 11973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Statement 11983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // FunctionDeclaration 11993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 12003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // In harmony mode we allow additionally the following productions 12013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ModuleElement: 12023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // LetDeclaration 12033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ConstDeclaration 12043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ModuleDeclaration 12053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ImportDeclaration 12063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ExportDeclaration 12073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (peek()) { 12093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::FUNCTION: 12103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseFunctionDeclaration(NULL, ok); 12113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::LET: 12123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::CONST: 12133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseVariableStatement(kModuleElement, NULL, ok); 12143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::IMPORT: 12153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseImportDeclaration(ok); 12163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::EXPORT: 12173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseExportDeclaration(ok); 12183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: { 12193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Statement* stmt = ParseStatement(labels, CHECK_OK); 12203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Handle 'module' as a context-sensitive keyword. 12213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_harmony_modules && 12223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch peek() == Token::IDENTIFIER && 12233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !scanner().HasAnyLineTerminatorBeforeNext() && 12243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stmt != NULL) { 12253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpressionStatement* estmt = stmt->AsExpressionStatement(); 12263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (estmt != NULL && 12273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch estmt->expression()->AsVariableProxy() != NULL && 12283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch estmt->expression()->AsVariableProxy()->name()->Equals( 12293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->heap()->module_symbol()) && 12303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !scanner().literal_contains_escapes()) { 12313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseModuleDeclaration(NULL, ok); 12323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return stmt; 12353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12403ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochBlock* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { 12413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ModuleDeclaration: 12423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 'module' Identifier Module 12433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Create new block with one expected declaration. 12453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* block = factory()->NewBlock(NULL, 1, true); 12463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name = ParseIdentifier(CHECK_OK); 12473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 12493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interface_details) 12503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("# Module %s...\n", name->ToAsciiArray()); 12513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 12523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Module* module = ParseModule(CHECK_OK); 12543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* proxy = NewUnresolved(name, LET, module->interface()); 12553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Declaration* declaration = 12563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewModuleDeclaration(proxy, module, top_scope_); 12573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Declare(declaration, true, CHECK_OK); 12583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 12603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interface_details) 12613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("# Module %s.\n", name->ToAsciiArray()); 12623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interfaces) { 12643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("module %s : ", name->ToAsciiArray()); 12653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch module->interface()->Print(); 12663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 12683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(rossberg): Add initialization statement to block. 12703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (names) names->Add(name); 12723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return block; 12733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12763ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochModule* Parser::ParseModule(bool* ok) { 12773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Module: 12783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // '{' ModuleElement '}' 12793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // '=' ModulePath ';' 12803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 'at' String ';' 12813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (peek()) { 12833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::LBRACE: 12843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseModuleLiteral(ok); 12853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::ASSIGN: { 12873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expect(Token::ASSIGN, CHECK_OK); 12883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Module* result = ParseModulePath(CHECK_OK); 12893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpectSemicolon(CHECK_OK); 12903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return result; 12913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: { 12943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpectContextualKeyword("at", CHECK_OK); 12953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Module* result = ParseModuleUrl(CHECK_OK); 12963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpectSemicolon(CHECK_OK); 12973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return result; 12983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13033ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochModule* Parser::ParseModuleLiteral(bool* ok) { 13043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Module: 13053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // '{' ModuleElement '}' 13063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Construct block expecting 16 statements. 13083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* body = factory()->NewBlock(NULL, 16, false); 13093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 13103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interface_details) PrintF("# Literal "); 13113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 13123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* scope = NewScope(top_scope_, MODULE_SCOPE); 13133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expect(Token::LBRACE, CHECK_OK); 13153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->set_start_position(scanner().location().beg_pos); 13163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->SetLanguageMode(EXTENDED_MODE); 13173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 13193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BlockState block_state(this, scope); 13203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TargetCollector collector; 13213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Target target(&this->target_stack_, &collector); 13223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Target target_body(&this->target_stack_, body); 13233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InitializationBlockFinder block_finder(top_scope_, target_stack_); 13243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (peek() != Token::RBRACE) { 13263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Statement* stat = ParseModuleElement(NULL, CHECK_OK); 13273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (stat && !stat->IsEmpty()) { 13283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch body->AddStatement(stat); 13293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch block_finder.Update(stat); 13303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expect(Token::RBRACE, CHECK_OK); 13353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->set_end_position(scanner().location().end_pos); 13363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch body->set_block_scope(scope); 13373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->interface()->Freeze(ok); 13393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ok); 13403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewModuleLiteral(body, scope->interface()); 13413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13443ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochModule* Parser::ParseModulePath(bool* ok) { 13453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ModulePath: 13463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Identifier 13473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ModulePath '.' Identifier 13483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Module* result = ParseModuleVariable(CHECK_OK); 13503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (Check(Token::PERIOD)) { 13513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name = ParseIdentifierName(CHECK_OK); 13523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 13533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interface_details) 13543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("# Path .%s ", name->ToAsciiArray()); 13553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 13563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Module* member = factory()->NewModulePath(result, name); 13573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result->interface()->Add(name, member->interface(), ok); 13583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!*ok) { 13593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 13603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interfaces) { 13613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); 13623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("result: "); 13633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result->interface()->Print(); 13643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("member: "); 13653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch member->interface()->Print(); 13663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 13683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); 13693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return NULL; 13703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = member; 13723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return result; 13753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13783ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochModule* Parser::ParseModuleVariable(bool* ok) { 13793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ModulePath: 13803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Identifier 13813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name = ParseIdentifier(CHECK_OK); 13833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 13843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interface_details) 13853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("# Module variable %s ", name->ToAsciiArray()); 13863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 13873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* proxy = top_scope_->NewUnresolved( 13883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory(), name, scanner().location().beg_pos, Interface::NewModule()); 13893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewModuleVariable(proxy); 13913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13943ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochModule* Parser::ParseModuleUrl(bool* ok) { 13953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Module: 13963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // String 13973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expect(Token::STRING, CHECK_OK); 13993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> symbol = GetSymbol(CHECK_OK); 14003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(ES6): Request JS resource from environment... 14023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 14043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interface_details) PrintF("# Url "); 14053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 14063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewModuleUrl(symbol); 14073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 14083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14103ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochModule* Parser::ParseModuleSpecifier(bool* ok) { 14113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ModuleSpecifier: 14123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // String 14133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ModulePath 14143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (peek() == Token::STRING) { 14163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseModuleUrl(ok); 14173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 14183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseModulePath(ok); 14193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 14213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14233ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochBlock* Parser::ParseImportDeclaration(bool* ok) { 14243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ImportDeclaration: 14253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' 14263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 14273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(ES6): implement destructuring ImportSpecifiers 14283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expect(Token::IMPORT, CHECK_OK); 14303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ZoneStringList names(1); 14313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name = ParseIdentifierName(CHECK_OK); 14333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch names.Add(name); 14343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (peek() == Token::COMMA) { 14353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Consume(Token::COMMA); 14363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch name = ParseIdentifierName(CHECK_OK); 14373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch names.Add(name); 14383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpectContextualKeyword("from", CHECK_OK); 14413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Module* module = ParseModuleSpecifier(CHECK_OK); 14423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpectSemicolon(CHECK_OK); 14433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Generate a separate declaration for each identifier. 14453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(ES6): once we implement destructuring, make that one declaration. 14463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* block = factory()->NewBlock(NULL, 1, true); 14473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < names.length(); ++i) { 14483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 14493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interface_details) 14503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("# Import %s ", names[i]->ToAsciiArray()); 14513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 14523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Interface* interface = Interface::NewUnknown(); 14533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch module->interface()->Add(names[i], interface, ok); 14543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!*ok) { 14553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 14563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interfaces) { 14573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); 14583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("module: "); 14593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch module->interface()->Print(); 14603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 14623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); 14633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return NULL; 14643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* proxy = NewUnresolved(names[i], LET, interface); 14663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Declaration* declaration = 14673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewImportDeclaration(proxy, module, top_scope_); 14683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Declare(declaration, true, CHECK_OK); 14693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(rossberg): Add initialization statement to block. 14703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return block; 14733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 14743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14763ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochStatement* Parser::ParseExportDeclaration(bool* ok) { 14773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ExportDeclaration: 14783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 'export' Identifier (',' Identifier)* ';' 14793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 'export' VariableDeclaration 14803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 'export' FunctionDeclaration 14813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 'export' ModuleDeclaration 14823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 14833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(ES6): implement structuring ExportSpecifiers 14843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expect(Token::EXPORT, CHECK_OK); 14863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Statement* result = NULL; 14883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ZoneStringList names(1); 14893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (peek()) { 14903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::IDENTIFIER: { 14913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name = ParseIdentifier(CHECK_OK); 14923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Handle 'module' as a context-sensitive keyword. 14933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!name->IsEqualTo(CStrVector("module"))) { 14943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch names.Add(name); 14953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (peek() == Token::COMMA) { 14963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Consume(Token::COMMA); 14973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch name = ParseIdentifier(CHECK_OK); 14983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch names.Add(name); 14993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpectSemicolon(CHECK_OK); 15013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewEmptyStatement(); 15023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 15033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = ParseModuleDeclaration(&names, CHECK_OK); 15043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 15063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::FUNCTION: 15093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = ParseFunctionDeclaration(&names, CHECK_OK); 15103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 15113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::VAR: 15133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::LET: 15143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::CONST: 15153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); 15163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 15173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 15193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *ok = false; 15203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReportUnexpectedToken(scanner().current_token()); 15213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return NULL; 15223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Extract declared names into export declarations and interface. 15253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Interface* interface = top_scope_->interface(); 15263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < names.length(); ++i) { 15273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 15283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interface_details) 15293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("# Export %s ", names[i]->ToAsciiArray()); 15303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 15313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Interface* inner = Interface::NewUnknown(); 15323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch interface->Add(names[i], inner, CHECK_OK); 15333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* proxy = NewUnresolved(names[i], LET, inner); 15343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch USE(proxy); 15353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(rossberg): Rethink whether we actually need to store export 15363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // declarations (for compilation?). 15373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ExportDeclaration* declaration = 15383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // factory()->NewExportDeclaration(proxy, top_scope_); 15393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // top_scope_->AddDeclaration(declaration); 15403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(result != NULL); 15433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return result; 15443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 15453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15473ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochStatement* Parser::ParseBlockElement(ZoneStringList* labels, 15483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool* ok) { 15493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // (Ecma 262 5th Edition, clause 14): 15503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // SourceElement: 15513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Statement 15523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // FunctionDeclaration 15533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 15543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // In harmony mode we allow additionally the following productions 15553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // BlockElement (aka SourceElement): 15563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // LetDeclaration 15573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ConstDeclaration 15583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (peek()) { 15603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::FUNCTION: 15613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseFunctionDeclaration(NULL, ok); 15623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::LET: 15633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::CONST: 15643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseVariableStatement(kModuleElement, NULL, ok); 15653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 15663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseStatement(labels, ok); 15673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 15693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStatement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { 1572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Statement :: 1573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Block 1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // VariableStatement 1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // EmptyStatement 1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ExpressionStatement 1577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // IfStatement 1578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // IterationStatement 1579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ContinueStatement 1580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // BreakStatement 1581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ReturnStatement 1582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // WithStatement 1583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // LabelledStatement 1584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // SwitchStatement 1585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ThrowStatement 1586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // TryStatement 1587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // DebuggerStatement 1588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note: Since labels can only be used by 'break' and 'continue' 1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // statements, which themselves are only valid within blocks, 1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // iterations or 'switch' statements (i.e., BreakableStatements), 1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // labels can be simply ignored in all other cases; except for 1593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // trivial labeled break statements 'label: break label' which is 1594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parsed into an empty statement. 1595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Keep the source position of the statement 1597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int statement_pos = scanner().peek_location().beg_pos; 1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* stmt = NULL; 1599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (peek()) { 1600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::LBRACE: 1601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ParseBlock(labels, ok); 1602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::CONST: // fall through 16043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::LET: 1605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::VAR: 16063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stmt = ParseVariableStatement(kStatement, NULL, ok); 1607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::SEMICOLON: 1610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 16113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewEmptyStatement(); 1612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::IF: 1614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stmt = ParseIfStatement(labels, ok); 1615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::DO: 16183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block stmt = ParseDoWhileStatement(labels, ok); 1619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::WHILE: 1622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stmt = ParseWhileStatement(labels, ok); 1623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::FOR: 1626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stmt = ParseForStatement(labels, ok); 1627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::CONTINUE: 1630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stmt = ParseContinueStatement(ok); 1631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::BREAK: 1634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stmt = ParseBreakStatement(labels, ok); 1635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::RETURN: 1638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stmt = ParseReturnStatement(ok); 1639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::WITH: 1642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stmt = ParseWithStatement(labels, ok); 1643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::SWITCH: 1646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stmt = ParseSwitchStatement(labels, ok); 1647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::THROW: 1650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stmt = ParseThrowStatement(ok); 1651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::TRY: { 1654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // NOTE: It is somewhat complicated to have labels on 1655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // try-statements. When breaking out of a try-finally statement, 1656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // one must take great care not to treat it as a 1657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // fall-through. It is much easier just to wrap the entire 1658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // try-statement in a statement block and put the labels there 16593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* result = factory()->NewBlock(labels, 1, false); 16603e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Target target(&this->target_stack_, result); 1661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TryStatement* statement = ParseTryStatement(CHECK_OK); 1662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (statement) { 1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block statement->set_statement_pos(statement_pos); 1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result) result->AddStatement(statement); 1666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 1667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1669e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch case Token::FUNCTION: { 16703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // FunctionDeclaration is only allowed in the context of SourceElements 16713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // (Ecma 262 5th Edition, clause 14): 16723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // SourceElement: 16733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Statement 16743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // FunctionDeclaration 16753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Common language extension is to allow function declaration in place 16763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // of any statement. This language extension is disabled in strict mode. 16773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!top_scope_->is_classic_mode()) { 1678e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ReportMessageAt(scanner().peek_location(), "strict_function", 1679e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Vector<const char*>::empty()); 1680e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *ok = false; 1681e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return NULL; 1682e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 16833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ParseFunctionDeclaration(NULL, ok); 1684e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::DEBUGGER: 1687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stmt = ParseDebuggerStatement(ok); 1688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 1691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stmt = ParseExpressionOrLabelledStatement(labels, ok); 1692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Store the source position of the statement 1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (stmt != NULL) stmt->set_statement_pos(statement_pos); 1696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return stmt; 1697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17003ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochVariableProxy* Parser::NewUnresolved( 17013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name, VariableMode mode, Interface* interface) { 170269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // If we are inside a function, a declaration of a var/const variable is a 170369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // truly local variable, and the scope of the variable is always the function 170469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // scope. 17053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Let/const variables in harmony mode are always added to the immediately 17063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // enclosing scope. 17073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return DeclarationScope(mode)->NewUnresolved( 17083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory(), name, scanner().location().beg_pos, interface); 17093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 17103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { 17133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* proxy = declaration->proxy(); 17143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name = proxy->name(); 17153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableMode mode = declaration->mode(); 17163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* declaration_scope = DeclarationScope(mode); 17173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Variable* var = NULL; 1718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If a function scope exists, then we can statically declare this 1720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // variable and also set its mode. In any case, a Declaration node 1721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // will be added to the scope so that the declaration can be added 1722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to the corresponding activation frame at runtime if necessary. 1723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For instance declarations inside an eval scope need to be added 1724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to the calling function context. 1725257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Similarly, strict mode eval scope does not leak variable declarations to 1726257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // the caller's scope so we declare all locals, too. 17273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Also for block scoped let/const bindings the variable can be 17283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // statically declared. 17293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (declaration_scope->is_function_scope() || 17303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch declaration_scope->is_strict_or_extended_eval_scope() || 17313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch declaration_scope->is_block_scope() || 17323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch declaration_scope->is_module_scope() || 17333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch declaration->AsModuleDeclaration() != NULL) { 1734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Declare the variable in the function scope. 17353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch var = declaration_scope->LocalLookup(name); 1736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (var == NULL) { 1737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Declare the name. 17383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var = declaration_scope->DeclareLocal( 17393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch name, mode, declaration->initialization(), proxy->interface()); 1740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1741589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // The name was declared in this scope before; check for conflicting 1742589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // re-declarations. We have a conflict if either of the declarations is 1743589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // not a var. There is similar code in runtime.cc in the Declare 1744589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // functions. The function CheckNonConflictingScope checks for conflicting 1745589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // var and let bindings from different scopes whereas this is a check for 1746589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // conflicting declarations within the same scope. This check also covers 1747589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // 1748589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // function () { let x; { var x; } } 1749589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // 1750589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // because the var declaration is hoisted to the function scope where 'x' 1751589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // is already bound. 17523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((mode != VAR) || (var->mode() != VAR)) { 175369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // We only have vars, consts and lets in declarations. 17543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(var->mode() == VAR || 17553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var->mode() == CONST || 17563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var->mode() == CONST_HARMONY || 17573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var->mode() == LET); 17583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (is_extended_mode()) { 1759589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // In harmony mode we treat re-declarations as early errors. See 1760589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // ES5 16 for a definition of early errors. 1761589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); 1762589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch const char* elms[2] = { "Variable", *c_string }; 1763589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Vector<const char*> args(elms, 2); 1764589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ReportMessage("redeclaration", args); 1765589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch *ok = false; 17663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 1767589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 17683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* type = (var->mode() == VAR) 17693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? "var" : var->is_const_mode() ? "const" : "let"; 1770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> type_string = 177144f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); 1772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* expression = 177344f0eee88ff00398ff7f715fab053374d808c90dSteve Block NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), 1774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block type_string, name); 17753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch declaration_scope->SetIllegalRedeclaration(expression); 1776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We add a declaration node for every declaration. The compiler 1781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // will only generate code if necessary. In particular, declarations 1782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for inner local variables that do not represent functions won't 1783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // result in any generated code. 1784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note that we always add an unresolved proxy even if it's not 1786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // used, simply because we don't know in this method (w/o extra 1787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parameters) if the proxy is needed or not. The proxy will be 1788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bound during variable resolution time unless it was pre-bound 1789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // below. 1790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // WARNING: This will lead to multiple declaration nodes for the 1792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // same variable if it is declared several times. This is not a 1793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // semantic issue as long as we keep the source order, but it may be 1794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a performance issue since it may lead to repeated 1795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Runtime::DeclareContextSlot() calls. 17963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch declaration_scope->AddDeclaration(declaration); 1797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((mode == CONST || mode == CONST_HARMONY) && 17993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch declaration_scope->is_global_scope()) { 18003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // For global const variables we bind the proxy to a variable. 1801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(resolve); // should be set by all callers 1802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Variable::Kind kind = Variable::NORMAL; 18033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch var = new(zone()) Variable(declaration_scope, 18043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch name, 18053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mode, 1806592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch true, 18073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kind, 18083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kNeedsInitialization); 18093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (declaration_scope->is_eval_scope() && 18103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch declaration_scope->is_classic_mode()) { 18113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // For variable declarations in a non-strict eval scope the proxy is bound 18123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to a lookup variable to force a dynamic declaration using the 18133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // DeclareContextSlot runtime function. 18143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Variable::Kind kind = Variable::NORMAL; 18153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var = new(zone()) Variable(declaration_scope, 18163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch name, 18173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mode, 18183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch true, 18193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kind, 18203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch declaration->initialization()); 18213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var->AllocateTo(Variable::LOOKUP, -1); 18223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch resolve = true; 1823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If requested and we have a local variable, bind the proxy to the variable 1826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // at parse-time. This is used for functions (and consts) declared inside 1827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // statements: the corresponding function (or const) variable must be in the 1828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function scope and not a statement-local scope, e.g. as provided with a 1829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'with' statement: 1830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // with (obj) { 1832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function f() {} 1833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // } 1834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // which is translated into: 1836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // with (obj) { 1838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // // in this case this is not: 'var f; f = function () {};' 1839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // var f = function () {}; 1840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // } 1841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note that if 'f' is accessed from inside the 'with' statement, it 1843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // will be allocated in the context (because we must be able to look 1844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // it up dynamically) but it will also be accessed statically, i.e., 1845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // with a context slot index and a context chain length for this 1846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // initialization code. Thus, inside the 'with' statement, we need 1847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // both access to the static and the dynamic context chain; the 1848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // runtime needs to provide both. 18493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (resolve && var != NULL) { 18503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch proxy->BindTo(var); 1851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 18523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_harmony_modules) { 18533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool ok; 18543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 18553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interface_details) 18563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("# Declare %s\n", var->name()->ToAsciiArray()); 18573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 18583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch proxy->interface()->Unify(var->interface(), &ok); 18593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!ok) { 18603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 18613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interfaces) { 18623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("DECLARE TYPE ERROR\n"); 18633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("proxy: "); 18643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch proxy->interface()->Print(); 18653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("var: "); 18663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var->interface()->Print(); 18673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 18683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 18693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1)); 18703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 18713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 18723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Language extension which is only enabled for source files loaded 1877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// through the API's extension mechanism. A native function 1878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// declaration is resolved by looking up the function through a 1879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// callback provided by the extension. 1880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStatement* Parser::ParseNativeDeclaration(bool* ok) { 1881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::FUNCTION, CHECK_OK); 1882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name = ParseIdentifier(CHECK_OK); 1883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LPAREN, CHECK_OK); 1884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done = (peek() == Token::RPAREN); 1885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!done) { 1886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ParseIdentifier(CHECK_OK); 1887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block done = (peek() == Token::RPAREN); 18883e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (!done) { 18893e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Expect(Token::COMMA, CHECK_OK); 18903e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu } 1891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 1893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::SEMICOLON, CHECK_OK); 1894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that the function containing the native declaration 1896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // isn't lazily compiled. The extension structures are only 1897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // accessible while parsing the first time not when reparsing 1898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // because of lazy compilation. 18993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeclarationScope(VAR)->ForceEagerCompilation(); 1900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the function template for the native function. 1902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::FunctionTemplate> fun_template = 1903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block extension_->GetNativeFunction(v8::Utils::ToLocal(name)); 1904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!fun_template.IsEmpty()); 1905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Instantiate the function and create a shared function info from it. 1907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction()); 1908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int literals = fun->NumberOfLiterals(); 1909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>(fun->shared()->code()); 1910e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); 19116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> shared = 191244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()->NewSharedFunctionInfo(name, literals, code, 19133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<ScopeInfo>(fun->shared()->scope_info())); 19146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block shared->set_construct_stub(*construct_stub); 19156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 19166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Copy the function data to the shared function info. 19176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block shared->set_function_data(fun->shared()->function_data()); 1918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int parameters = fun->shared()->formal_parameter_count(); 19196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block shared->set_formal_parameter_count(parameters); 1920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // TODO(1240846): It's weird that native function declarations are 1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // introduced dynamically when we meet their declarations, whereas 19233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // other functions are set up when entering the surrounding scope. 19243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* proxy = NewUnresolved(name, VAR); 19253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Declaration* declaration = 19263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewVariableDeclaration(proxy, VAR, top_scope_); 19273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Declare(declaration, true, CHECK_OK); 19288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SharedFunctionInfoLiteral* lit = 19293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewSharedFunctionInfoLiteral(shared); 19303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewExpressionStatement( 19313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewAssignment( 19323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); 1933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19363ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochStatement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { 1937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // FunctionDeclaration :: 1938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 1939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::FUNCTION, CHECK_OK); 1940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int function_token_position = scanner().location().beg_pos; 19413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_strict_reserved = false; 19423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> name = ParseIdentifierOrStrictReservedWord( 19433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch &is_strict_reserved, CHECK_OK); 1944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionLiteral* fun = ParseFunctionLiteral(name, 19453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch is_strict_reserved, 1946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block function_token_position, 19473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch FunctionLiteral::DECLARATION, 1948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_OK); 1949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Even if we're not at the top-level of the global or a function 1950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // scope, we treat is as such and introduce the function with it's 1951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // initial value upon entering the corresponding scope. 19523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableMode mode = is_extended_mode() ? LET : VAR; 19533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* proxy = NewUnresolved(name, mode); 19543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Declaration* declaration = 19553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_); 19563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Declare(declaration, true, CHECK_OK); 19573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (names) names->Add(name); 19583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewEmptyStatement(); 1959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBlock* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { 19633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); 196469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Block :: 1966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '{' Statement* '}' 1967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note that a Block does not introduce a new execution scope! 1969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // (ECMA-262, 3rd, 12.2) 1970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Construct block expecting 16 statements. 19723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* result = factory()->NewBlock(labels, 16, false); 19733e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Target target(&this->target_stack_, result); 1974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LBRACE, CHECK_OK); 19753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch InitializationBlockFinder block_finder(top_scope_, target_stack_); 1976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (peek() != Token::RBRACE) { 1977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* stat = ParseStatement(NULL, CHECK_OK); 19783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (stat && !stat->IsEmpty()) { 19793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result->AddStatement(stat); 19803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch block_finder.Update(stat); 19813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RBRACE, CHECK_OK); 1984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 1985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 198869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochBlock* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { 19893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The harmony mode uses block elements instead of statements. 19903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 19913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Block :: 19923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // '{' BlockElement* '}' 19933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 199469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Construct block expecting 16 statements. 19953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* body = factory()->NewBlock(labels, 16, false); 19963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); 199769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 199869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Parse the statements and collect escaping labels. 199969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Expect(Token::LBRACE, CHECK_OK); 20003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch block_scope->set_start_position(scanner().location().beg_pos); 20013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { BlockState block_state(this, block_scope); 20023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TargetCollector collector; 20033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Target target(&this->target_stack_, &collector); 200469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Target target_body(&this->target_stack_, body); 200569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch InitializationBlockFinder block_finder(top_scope_, target_stack_); 200669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 200769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch while (peek() != Token::RBRACE) { 20083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Statement* stat = ParseBlockElement(NULL, CHECK_OK); 200969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (stat && !stat->IsEmpty()) { 201069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch body->AddStatement(stat); 201169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch block_finder.Update(stat); 201269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 201369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 201469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 201569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Expect(Token::RBRACE, CHECK_OK); 20163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch block_scope->set_end_position(scanner().location().end_pos); 2017589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch block_scope = block_scope->FinalizeBlockScope(); 2018589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch body->set_block_scope(block_scope); 2019589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return body; 202069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 202169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 202269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 202369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochBlock* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 20243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ZoneStringList* names, 202569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch bool* ok) { 2026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // VariableStatement :: 2027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // VariableDeclarations ';' 2028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> ignore; 20303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* result = 20313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); 2032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectSemicolon(CHECK_OK); 2033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 2034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 203644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 203744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Parser::IsEvalOrArguments(Handle<String> string) { 203844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return string.is_identical_to(isolate()->factory()->eval_symbol()) || 203944f0eee88ff00398ff7f715fab053374d808c90dSteve Block string.is_identical_to(isolate()->factory()->arguments_symbol()); 20401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 2041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 204244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If the variable declaration declares exactly one non-const 20443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// variable, then *out is set to that variable. In all other cases, 20453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// *out is untouched; in particular, it is the caller's responsibility 2046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to initialize it properly. This mechanism is used for the parsing 2047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// of 'for-in' loops. 20483ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochBlock* Parser::ParseVariableDeclarations( 20493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableDeclarationContext var_context, 20503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableDeclarationProperties* decl_props, 20513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ZoneStringList* names, 20523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String>* out, 20533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool* ok) { 2054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // VariableDeclarations :: 20553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] 20563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 20573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The ES6 Draft Rev3 specifies the following grammar for const declarations 20583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 20593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ConstDeclaration :: 20603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // const ConstBinding (',' ConstBinding)* ';' 20613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ConstBinding :: 20623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Identifier '=' AssignmentExpression 20633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 20643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(ES6): 20653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ConstBinding :: 20663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // BindingPattern '=' AssignmentExpression 20673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableMode mode = VAR; 206869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // True if the binding needs initialization. 'let' and 'const' declared 206969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // bindings are created uninitialized by their declaration nodes and 207069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // need initialization. 'var' declared bindings are always initialized 207169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // immediately by their declaration nodes. 207269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch bool needs_init = false; 2073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_const = false; 207469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Token::Value init_op = Token::INIT_VAR; 2075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() == Token::VAR) { 2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::VAR); 2077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (peek() == Token::CONST) { 20783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: 20793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 20803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 20813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 20823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // * It is a Syntax Error if the code that matches this production is not 20833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // contained in extended code. 20843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 20853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // However disallowing const in classic mode will break compatibility with 20863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // existing pages. Therefore we keep allowing const with the old 20873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // non-harmony semantics in classic mode. 2088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::CONST); 20893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (top_scope_->language_mode()) { 20903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CLASSIC_MODE: 20913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mode = CONST; 20923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch init_op = Token::INIT_CONST; 20933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 20943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case STRICT_MODE: 20953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReportMessage("strict_const", Vector<const char*>::empty()); 20963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *ok = false; 20973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return NULL; 20983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTENDED_MODE: 20993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (var_context == kStatement) { 21003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // In extended mode 'const' declarations are only allowed in source 21013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // element positions. 21023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReportMessage("unprotected_const", Vector<const char*>::empty()); 21033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *ok = false; 21043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return NULL; 21053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 21063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mode = CONST_HARMONY; 21073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch init_op = Token::INIT_CONST_HARMONY; 2108e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_const = true; 211069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch needs_init = true; 211169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else if (peek() == Token::LET) { 21123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ES6 Draft Rev4 section 12.2.1: 21133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 21143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // LetDeclaration : let LetBindingList ; 21153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 21163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // * It is a Syntax Error if the code that matches this production is not 21173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // contained in extended code. 21183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!is_extended_mode()) { 21193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReportMessage("illegal_let", Vector<const char*>::empty()); 21203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *ok = false; 21213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return NULL; 21223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 212369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Consume(Token::LET); 21243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (var_context == kStatement) { 21253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Let declarations are only allowed in source element positions. 212669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ReportMessage("unprotected_let", Vector<const char*>::empty()); 212769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch *ok = false; 212869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return NULL; 212969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 21303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mode = LET; 213169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch needs_init = true; 213269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch init_op = Token::INIT_LET; 2133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNREACHABLE(); // by current callers 2135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* declaration_scope = DeclarationScope(mode); 21383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 213969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // The scope of a var/const declared variable anywhere inside a function 2140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 214169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // transform a source-level var/const declaration into a (Function) 2142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scope declaration, and rewrite the source-level initialization into an 2143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // assignment statement. We use a block to collect multiple assignments. 2144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We mark the block as initializer block because we don't want the 2146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // rewriter to add a '.result' assignment to such a block (to get compliant 2147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // behavior for code such as print(eval('var x = 7')), and for cosmetic 2148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // reasons when pretty-printing. Also, unless an assignment (initialization) 2149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is inside an initializer block, it is ignored. 2150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create new block with one expected declaration. 21523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* block = factory()->NewBlock(NULL, 1, true); 2153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int nvars = 0; // the number of variables declared 21543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> name; 2155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { 215680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->Enter(); 215780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 2158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parse variable name. 2159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (nvars > 0) Consume(Token::COMMA); 21603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch name = ParseIdentifier(CHECK_OK); 216180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->PushVariableName(name); 2162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Strict mode variables may not be named eval or arguments 21643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) { 21651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ReportMessage("strict_var_name", Vector<const char*>::empty()); 21661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 21671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return NULL; 21681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 21691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Declare variable. 2171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note that we *always* must treat the initial value via a separate init 2172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // assignment for variables and constants because the value must be assigned 2173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // when the variable is encountered in the source. But the variable/constant 2174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is declared (and set to 'undefined') upon entering the function within 2175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // which the variable or constant is declared. Only function variables have 2176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an initial value in the declaration (because they are initialized upon 2177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // entering the function). 2178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we have a const declaration, in an inner scope, the proxy is always 2180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bound to the declared variable (independent of possibly surrounding with 2181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // statements). 21823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // For let/const declarations in harmony mode, we can also immediately 21833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // pre-resolve the proxy because it resides in the same scope as the 21843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // declaration. 21853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* proxy = NewUnresolved(name, mode); 21863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Declaration* declaration = 21873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewVariableDeclaration(proxy, mode, top_scope_); 21883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Declare(declaration, mode != VAR, CHECK_OK); 2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block nvars++; 21903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { 2191053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block ReportMessageAt(scanner().location(), "too_many_variables", 2192053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block Vector<const char*>::empty()); 2193053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block *ok = false; 2194053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block return NULL; 2195053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block } 21963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (names) names->Add(name); 2197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parse initialization expression if present and/or needed. A 2199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // declaration of the form: 2200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // var v = x; 2202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is syntactic sugar for: 2204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // var v; v = x; 2206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 22073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // In particular, we need to re-lookup 'v' (in top_scope_, not 22083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // declaration_scope) as it may be a different 'v' than the 'v' in the 22093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // declaration (e.g., if we are inside a 'with' statement or 'catch' 22103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // block). 2211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // However, note that const declarations are different! A const 2213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // declaration of the form: 2214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // const c = x; 2216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is *not* syntactic sugar for: 2218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // const c; c = x; 2220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The "variable" c initialized to x is the same as the declared 2222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // one - there is no re-lookup (see the last parameter of the 2223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Declare() call above). 2224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 22253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Scope* initialization_scope = is_const ? declaration_scope : top_scope_; 2226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* value = NULL; 2227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int position = -1; 22283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Harmony consts have non-optional initializers. 22293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { 2230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::ASSIGN, CHECK_OK); 2231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block position = scanner().location().beg_pos; 223269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 223380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Don't infer if it is "a = function(){...}();"-like expression. 22343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (fni_ != NULL && 22353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch value->AsCall() == NULL && 22363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch value->AsCallNew() == NULL) { 22373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fni_->Infer(); 223869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 223969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch fni_->RemoveLastFunction(); 22403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 22413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (decl_props != NULL) *decl_props = kHasInitializers; 22423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 22433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Record the end position of the initializer. 22453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (proxy->var() != NULL) { 22463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch proxy->var()->set_initializer_position(scanner().location().end_pos); 2247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Make sure that 'const x' and 'let x' initialize 'x' to undefined. 225069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (value == NULL && needs_init) { 2251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value = GetLiteralUndefined(); 2252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Global variable declarations must be compiled in a specific 2255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // way. When the script containing the global variable declaration 2256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is entered, the global variable must be declared, so that if it 2257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // doesn't exist (not even in a prototype of the global object) it 2258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // gets created with an initial undefined value. This is handled 2259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by the declarations part of the function representing the 2260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // top-level global code; see Runtime::DeclareGlobalVariable. If 2261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // it already exists (in the object or in a prototype), it is 2262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // *not* touched until the variable declaration statement is 2263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // executed. 2264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Executing the variable declaration statement will always 2266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // guarantee to give the global object a "local" variable; a 2267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // variable defined in the global object and not in any 2268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype. This way, global variable declarations can shadow 2269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // properties in the prototype chain, but only after the variable 2270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // declaration statement has been executed. This is important in 2271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // browsers where the global object (window) has lots of 2272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // properties defined in prototype objects. 22733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (initialization_scope->is_global_scope()) { 2274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the arguments for the runtime call. 2275257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3); 22768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // We have at least 1 parameter. 22773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch arguments->Add(factory()->NewLiteral(name)); 2278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CallRuntime* initialize; 2279e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_const) { 2281e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch arguments->Add(value); 2282e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch value = NULL; // zap the value to avoid the unnecessary assignment 2283e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2284e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Construct the call to Runtime_InitializeConstGlobal 2285e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // and add it to the initialization statement block. 2286e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Note that the function does different things depending on 2287e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // the number of arguments (1 or 2). 22883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch initialize = factory()->NewCallRuntime( 22893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->factory()->InitializeConstGlobal_symbol(), 22903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Runtime::FunctionForId(Runtime::kInitializeConstGlobal), 22913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch arguments); 2292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2293e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Add strict mode. 2294e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // We may want to pass singleton to avoid Literal allocations. 22953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LanguageMode language_mode = initialization_scope->language_mode(); 22963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch arguments->Add(factory()->NewNumberLiteral(language_mode)); 2297e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2298e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Be careful not to assign a value to the global variable if 2299e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // we're in a with. The initialization value should not 2300e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // necessarily be stored in the global object in that case, 2301e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // which is why we need to generate a separate assignment node. 2302e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (value != NULL && !inside_with()) { 2303e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch arguments->Add(value); 2304e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch value = NULL; // zap the value to avoid the unnecessary assignment 2305e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2306e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2307e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Construct the call to Runtime_InitializeVarGlobal 2308e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // and add it to the initialization statement block. 2309e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Note that the function does different things depending on 2310e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // the number of arguments (2 or 3). 23113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch initialize = factory()->NewCallRuntime( 23123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->factory()->InitializeVarGlobal_symbol(), 23133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Runtime::FunctionForId(Runtime::kInitializeVarGlobal), 23143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch arguments); 2315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2316e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 23173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch block->AddStatement(factory()->NewExpressionStatement(initialize)); 23183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (needs_init) { 23193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Constant initializations always assign to the declared constant which 23203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // is always at the function scope level. This is only relevant for 23213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // dynamically looked-up variables and constants (the start context for 23223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // constant lookups is always the function context, while it is the top 23233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // context for var declared variables). Sigh... 23243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // For 'let' and 'const' declared variables in harmony mode the 23253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // initialization also always assigns to the declared variable. 23263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(proxy != NULL); 23273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(proxy->var() != NULL); 23283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(value != NULL); 23293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Assignment* assignment = 23303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewAssignment(init_op, proxy, value, position); 23313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch block->AddStatement(factory()->NewExpressionStatement(assignment)); 23323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value = NULL; 2333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2335589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Add an assignment node to the initialization statement block if we still 23363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // have a pending initialization value. 2337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value != NULL) { 23383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(mode == VAR); 23393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 'var' initializations are simply assignments (with all the consequences 23403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // if they are inside a 'with' statement - they may change a 'with' object 23413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // property). 23425d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch VariableProxy* proxy = 23433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch initialization_scope->NewUnresolved(factory(), name); 23448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Assignment* assignment = 23453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewAssignment(init_op, proxy, value, position); 23463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch block->AddStatement(factory()->NewExpressionStatement(assignment)); 2347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 234880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 234980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->Leave(); 2350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (peek() == Token::COMMA); 2351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If there was a single non-const declaration, return it in the output 23533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // parameter for possible use by for/in. 23543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (nvars == 1 && !is_const) { 23553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch *out = name; 2356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return block; 2359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { 2363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!label.is_null()); 2364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (labels != NULL) 2365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = labels->length(); i-- > 0; ) 2366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (labels->at(i).is_identical_to(label)) 2367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 2368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 2370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStatement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, 2374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* ok) { 2375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ExpressionStatement | LabelledStatement :: 2376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Expression ';' 2377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Identifier ':' Statement 23781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool starts_with_idenfifier = peek_any_identifier(); 2379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* expr = ParseExpression(true, CHECK_OK); 23803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && 2381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expr->AsVariableProxy() != NULL && 2382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !expr->AsVariableProxy()->is_this()) { 23838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // Expression is a single identifier, and not, e.g., a parenthesized 23848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // identifier. 2385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VariableProxy* var = expr->AsVariableProxy(); 2386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> label = var->name(); 2387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // TODO(1240780): We don't check for redeclaration of labels 2388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // during preparsing since keeping track of the set of active 2389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // labels requires nontrivial changes to the way scopes are 2390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // structured. However, these are probably changes we want to 2391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // make later anyway so we should go back and fix this then. 23923e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { 2393589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS); 23943e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu const char* elms[2] = { "Label", *c_string }; 23953e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Vector<const char*> args(elms, 2); 23963e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu ReportMessage("redeclaration", args); 23973e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu *ok = false; 23983e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu return NULL; 2399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (labels == NULL) labels = new(zone()) ZoneStringList(4); 24013e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu labels->Add(label); 24023e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Remove the "ghost" variable that turned out to be a label 24033e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // from the top scope. This way, we don't try to resolve it 24043e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // during the scope processing. 24053e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu top_scope_->RemoveUnresolved(var); 2406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::COLON, CHECK_OK); 2407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ParseStatement(labels, ok); 2408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If we have an extension, we allow a native function declaration. 24113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // A native function declaration starts with "native function" with 24123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // no line-terminator between the two words. 24133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (extension_ != NULL && 24143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch peek() == Token::FUNCTION && 24153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch !scanner().HasAnyLineTerminatorBeforeNext() && 24163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch expr != NULL && 24173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch expr->AsVariableProxy() != NULL && 24183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch expr->AsVariableProxy()->name()->Equals( 24193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate()->heap()->native_symbol()) && 24203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch !scanner().literal_contains_escapes()) { 24213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ParseNativeDeclaration(ok); 24223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 24233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 24243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Parsed expression statement, or the context-sensitive 'module' keyword. 24253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Only expect semicolon in the former case. 24263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!FLAG_harmony_modules || 24273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch peek() != Token::IDENTIFIER || 24283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scanner().HasAnyLineTerminatorBeforeNext() || 24293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expr->AsVariableProxy() == NULL || 24303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !expr->AsVariableProxy()->name()->Equals( 24313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->heap()->module_symbol()) || 24323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scanner().literal_contains_escapes()) { 24333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpectSemicolon(CHECK_OK); 24343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 24353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewExpressionStatement(expr); 2436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockIfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { 2440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // IfStatement :: 2441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'if' '(' Expression ')' Statement ('else' Statement)? 2442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::IF, CHECK_OK); 2444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LPAREN, CHECK_OK); 2445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* condition = ParseExpression(true, CHECK_OK); 2446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 2447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* then_statement = ParseStatement(labels, CHECK_OK); 2448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* else_statement = NULL; 2449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() == Token::ELSE) { 2450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 2451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else_statement = ParseStatement(labels, CHECK_OK); 24523e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu } else { 24533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch else_statement = factory()->NewEmptyStatement(); 2454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 24553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewIfStatement(condition, then_statement, else_statement); 2456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStatement* Parser::ParseContinueStatement(bool* ok) { 2460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ContinueStatement :: 2461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'continue' Identifier? ';' 2462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::CONTINUE, CHECK_OK); 2464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> label = Handle<String>::null(); 2465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value tok = peek(); 24663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!scanner().HasAnyLineTerminatorBeforeNext() && 2467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 2468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block label = ParseIdentifier(CHECK_OK); 2469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IterationStatement* target = NULL; 24713e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu target = LookupContinueTarget(label, CHECK_OK); 24723e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (target == NULL) { 2473b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Illegal continue statement. 2474b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const char* message = "illegal_continue"; 2475b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Vector<Handle<String> > args; 2476b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (!label.is_null()) { 2477b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch message = "unknown_label"; 2478b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch args = Vector<Handle<String> >(&label, 1); 2479b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 2480b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ReportMessageAt(scanner().location(), message, args); 2481b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch *ok = false; 2482b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return NULL; 2483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectSemicolon(CHECK_OK); 24853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewContinueStatement(target); 2486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStatement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { 2490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // BreakStatement :: 2491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'break' Identifier? ';' 2492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::BREAK, CHECK_OK); 2494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> label; 2495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value tok = peek(); 24963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!scanner().HasAnyLineTerminatorBeforeNext() && 2497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 2498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block label = ParseIdentifier(CHECK_OK); 2499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parse labeled break statements that target themselves into 2501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // empty statements, e.g. 'l1: l2: l3: break l2;' 2502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!label.is_null() && ContainsLabel(labels, label)) { 25033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpectSemicolon(CHECK_OK); 25043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewEmptyStatement(); 2505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakableStatement* target = NULL; 25073e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu target = LookupBreakTarget(label, CHECK_OK); 25083e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (target == NULL) { 2509b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Illegal break statement. 2510b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const char* message = "illegal_break"; 2511b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Vector<Handle<String> > args; 2512b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (!label.is_null()) { 2513b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch message = "unknown_label"; 2514b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch args = Vector<Handle<String> >(&label, 1); 2515b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 2516b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ReportMessageAt(scanner().location(), message, args); 2517b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch *ok = false; 2518b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return NULL; 2519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectSemicolon(CHECK_OK); 25213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewBreakStatement(target); 2522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStatement* Parser::ParseReturnStatement(bool* ok) { 2526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ReturnStatement :: 2527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'return' Expression? ';' 2528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Consume the return token. It is necessary to do the before 2530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // reporting any errors on it, because of the way errors are 2531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // reported (underlining). 2532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RETURN, CHECK_OK); 2533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2534692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Token::Value tok = peek(); 2535692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Statement* result; 2536692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch if (scanner().HasAnyLineTerminatorBeforeNext() || 2537692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch tok == Token::SEMICOLON || 2538692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch tok == Token::RBRACE || 2539692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch tok == Token::EOS) { 2540692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch ExpectSemicolon(CHECK_OK); 25413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewReturnStatement(GetLiteralUndefined()); 2542692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch } else { 2543692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Expression* expr = ParseExpression(true, CHECK_OK); 2544692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch ExpectSemicolon(CHECK_OK); 25453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewReturnStatement(expr); 2546692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch } 2547692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 2548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // An ECMAScript program is considered syntactically incorrect if it 2549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // contains a return statement that is not within the body of a 2550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function. See ECMA-262, section 12.9, page 67. 2551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // To be consistent with KJS we report the syntax error at runtime. 25533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Scope* declaration_scope = top_scope_->DeclarationScope(); 25543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (declaration_scope->is_global_scope() || 25553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch declaration_scope->is_eval_scope()) { 255644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> type = isolate()->factory()->illegal_return_symbol(); 2557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); 25583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewExpressionStatement(throw_error); 2559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2560692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch return result; 2561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStatement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { 2565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // WithStatement :: 2566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'with' '(' Expression ')' Statement 2567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::WITH, CHECK_OK); 25691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 25703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!top_scope_->is_classic_mode()) { 25711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ReportMessage("strict_mode_with", Vector<const char*>::empty()); 25721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 25731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return NULL; 25741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 25751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LPAREN, CHECK_OK); 2577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* expr = ParseExpression(true, CHECK_OK); 2578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 2579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 258069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch top_scope_->DeclarationScope()->RecordWithStatement(); 25813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); 25823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Statement* stmt; 25833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { BlockState block_state(this, with_scope); 25843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch with_scope->set_start_position(scanner().peek_location().beg_pos); 25853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stmt = ParseStatement(labels, CHECK_OK); 25863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch with_scope->set_end_position(scanner().location().end_pos); 25873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewWithStatement(expr, stmt); 2589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { 2593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // CaseClause :: 2594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'case' Expression ':' Statement* 2595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'default' ':' Statement* 2596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* label = NULL; // NULL expression indicates default case 2598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() == Token::CASE) { 2599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::CASE, CHECK_OK); 2600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block label = ParseExpression(true, CHECK_OK); 2601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::DEFAULT, CHECK_OK); 2603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*default_seen_ptr) { 2604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportMessage("multiple_defaults_in_switch", 2605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<const char*>::empty()); 2606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *ok = false; 2607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 2608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *default_seen_ptr = true; 2610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::COLON, CHECK_OK); 2612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int pos = scanner().location().beg_pos; 2613257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneList<Statement*>* statements = new(zone()) ZoneList<Statement*>(5); 2614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (peek() != Token::CASE && 2615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block peek() != Token::DEFAULT && 2616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block peek() != Token::RBRACE) { 2617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* stat = ParseStatement(NULL, CHECK_OK); 26183e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu statements->Add(stat); 2619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return new(zone()) CaseClause(isolate(), label, statements, pos); 2622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, 2626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* ok) { 2627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // SwitchStatement :: 2628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'switch' '(' Expression ')' '{' CaseClause* '}' 2629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SwitchStatement* statement = factory()->NewSwitchStatement(labels); 26313e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Target target(&this->target_stack_, statement); 2632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::SWITCH, CHECK_OK); 2634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LPAREN, CHECK_OK); 2635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* tag = ParseExpression(true, CHECK_OK); 2636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 2637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool default_seen = false; 2639257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4); 2640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LBRACE, CHECK_OK); 2641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (peek() != Token::RBRACE) { 2642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); 26433e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu cases->Add(clause); 2644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RBRACE, CHECK_OK); 2646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26473e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (statement) statement->Initialize(tag, cases); 2648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return statement; 2649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStatement* Parser::ParseThrowStatement(bool* ok) { 2653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ThrowStatement :: 2654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'throw' Expression ';' 2655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::THROW, CHECK_OK); 2657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos = scanner().location().beg_pos; 26583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (scanner().HasAnyLineTerminatorBeforeNext()) { 2659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportMessage("newline_after_throw", Vector<const char*>::empty()); 2660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *ok = false; 2661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 2662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* exception = ParseExpression(true, CHECK_OK); 2664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectSemicolon(CHECK_OK); 2665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos)); 2667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTryStatement* Parser::ParseTryStatement(bool* ok) { 2671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // TryStatement :: 2672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'try' Block Catch 2673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'try' Block Finally 2674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'try' Block Catch Finally 2675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Catch :: 2677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'catch' '(' Identifier ')' Block 2678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Finally :: 2680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'finally' Block 2681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::TRY, CHECK_OK); 2683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch TargetCollector try_collector; 2685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Block* try_block; 2686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch { Target target(&this->target_stack_, &try_collector); 2688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block try_block = ParseBlock(NULL, CHECK_OK); 2689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value tok = peek(); 2692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (tok != Token::CATCH && tok != Token::FINALLY) { 2693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); 2694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *ok = false; 2695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 2696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we can break out from the catch block and there is a finally block, 26993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // then we will need to collect escaping targets from the catch 27003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // block. Since we don't know yet if there will be a finally block, we 27013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // always collect the targets. 27023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch TargetCollector catch_collector; 27033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Scope* catch_scope = NULL; 27043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Variable* catch_variable = NULL; 27053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Block* catch_block = NULL; 27063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> name; 2707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (tok == Token::CATCH) { 2708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::CATCH); 2709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LPAREN, CHECK_OK); 27113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch catch_scope = NewScope(top_scope_, CATCH_SCOPE); 27123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch catch_scope->set_start_position(scanner().location().beg_pos); 27133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch name = ParseIdentifier(CHECK_OK); 27141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 27153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) { 27161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ReportMessage("strict_catch_variable", Vector<const char*>::empty()); 27171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 27181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return NULL; 27191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 27201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 2722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() == Token::LBRACE) { 272469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Target target(&this->target_stack_, &catch_collector); 27253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableMode mode = is_extended_mode() ? LET : VAR; 27263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch catch_variable = 27273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch catch_scope->DeclareLocal(name, mode, kCreatedInitialized); 272869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 27293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BlockState block_state(this, catch_scope); 2730589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch catch_block = ParseBlock(NULL, CHECK_OK); 2731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LBRACE, CHECK_OK); 2733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 27343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch catch_scope->set_end_position(scanner().location().end_pos); 2735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tok = peek(); 2736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Block* finally_block = NULL; 27393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (tok == Token::FINALLY || catch_block == NULL) { 2740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::FINALLY); 2741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block finally_block = ParseBlock(NULL, CHECK_OK); 2742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Simplify the AST nodes by converting: 27453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 'try B0 catch B1 finally B2' 2746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to: 27473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 'try { try B0 catch B1 } finally B2' 2748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27493e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (catch_block != NULL && finally_block != NULL) { 27503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If we have both, create an inner try/catch. 27513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(catch_scope != NULL && catch_variable != NULL); 27523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int index = current_function_state_->NextHandlerIndex(); 27533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TryCatchStatement* statement = factory()->NewTryCatchStatement( 27543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch index, try_block, catch_scope, catch_variable, catch_block); 27553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch statement->set_escaping_targets(try_collector.targets()); 27563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch try_block = factory()->NewBlock(NULL, 1, false); 2757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block try_block->AddStatement(statement); 27583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch catch_block = NULL; // Clear to indicate it's been handled. 2759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TryStatement* result = NULL; 27623e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (catch_block != NULL) { 27633e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu ASSERT(finally_block == NULL); 27643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(catch_scope != NULL && catch_variable != NULL); 27653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int index = current_function_state_->NextHandlerIndex(); 27663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewTryCatchStatement( 27673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch index, try_block, catch_scope, catch_variable, catch_block); 27683e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu } else { 27693e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu ASSERT(finally_block != NULL); 27703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int index = current_function_state_->NextHandlerIndex(); 27713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewTryFinallyStatement(index, try_block, finally_block); 27723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Combine the jump targets of the try block and the possible catch block. 27733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch try_collector.targets()->AddAll(*catch_collector.targets()); 2774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result->set_escaping_targets(try_collector.targets()); 2777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 2778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockDoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, 27823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool* ok) { 2783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // DoStatement :: 2784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'do' Statement 'while' '(' Expression ')' ';' 2785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoWhileStatement* loop = factory()->NewDoWhileStatement(labels); 27873e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Target target(&this->target_stack_, loop); 2788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::DO, CHECK_OK); 2790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* body = ParseStatement(NULL, CHECK_OK); 2791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::WHILE, CHECK_OK); 2792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LPAREN, CHECK_OK); 2793d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 2794d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (loop != NULL) { 2795d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int position = scanner().location().beg_pos; 2796d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block loop->set_condition_position(position); 2797d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 2798d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 2799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* cond = ParseExpression(true, CHECK_OK); 2800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 2801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allow do-statements to be terminated with and without 2803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // semi-colons. This allows code such as 'do;while(0)return' to 2804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parse, which would not be the case if we had used the 2805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ExpectSemicolon() functionality here. 2806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 2807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (loop != NULL) loop->Initialize(cond, body); 2809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return loop; 2810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockWhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { 2814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // WhileStatement :: 2815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'while' '(' Expression ')' Statement 2816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch WhileStatement* loop = factory()->NewWhileStatement(labels); 28183e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Target target(&this->target_stack_, loop); 2819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::WHILE, CHECK_OK); 2821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LPAREN, CHECK_OK); 2822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* cond = ParseExpression(true, CHECK_OK); 2823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 2824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* body = ParseStatement(NULL, CHECK_OK); 2825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (loop != NULL) loop->Initialize(cond, body); 2827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return loop; 2828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStatement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { 2832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ForStatement :: 2833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 2834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* init = NULL; 2836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Create an in-between scope for let-bound iteration variables. 28383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* saved_scope = top_scope_; 28393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); 28403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_ = for_scope; 28413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::FOR, CHECK_OK); 2843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LPAREN, CHECK_OK); 28443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for_scope->set_start_position(scanner().location().beg_pos); 2845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() != Token::SEMICOLON) { 2846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() == Token::VAR || peek() == Token::CONST) { 28473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> name; 2848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Block* variable_statement = 28493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK); 28503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 28513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (peek() == Token::IN && !name.is_null()) { 28523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* each = top_scope_->NewUnresolved(factory(), name); 28533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ForInStatement* loop = factory()->NewForInStatement(labels); 28543e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Target target(&this->target_stack_, loop); 2855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::IN, CHECK_OK); 2857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* enumerable = ParseExpression(true, CHECK_OK); 2858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 2859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* body = ParseStatement(NULL, CHECK_OK); 28613e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu loop->Initialize(each, enumerable, body); 28623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* result = factory()->NewBlock(NULL, 2, false); 28633e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu result->AddStatement(variable_statement); 28643e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu result->AddStatement(loop); 28653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_ = saved_scope; 28663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for_scope->set_end_position(scanner().location().end_pos); 28673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for_scope = for_scope->FinalizeBlockScope(); 28683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(for_scope == NULL); 28693e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Parsed for-in loop w/ variable/const declaration. 28703e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu return result; 2871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block init = variable_statement; 2873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 28743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (peek() == Token::LET) { 28753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name; 28763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableDeclarationProperties decl_props = kHasNoInitializers; 28773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* variable_statement = 28783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, 28793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_OK); 28803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool accept_IN = !name.is_null() && decl_props != kHasInitializers; 28813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (peek() == Token::IN && accept_IN) { 28823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Rewrite a for-in statement of the form 28833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 28843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // for (let x in e) b 28853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 28863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // into 28873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 28883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // <let x' be a temporary variable> 28893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // for (x' in e) { 28903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // let x; 28913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // x = x'; 28923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // b; 28933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // } 28943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(keuchel): Move the temporary variable to the block scope, after 28963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // implementing stack allocated block scoped variables. 28973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Variable* temp = top_scope_->DeclarationScope()->NewTemporary(name); 28983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 28993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* each = top_scope_->NewUnresolved(factory(), name); 29003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ForInStatement* loop = factory()->NewForInStatement(labels); 29013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Target target(&this->target_stack_, loop); 29023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expect(Token::IN, CHECK_OK); 29043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expression* enumerable = ParseExpression(true, CHECK_OK); 29053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expect(Token::RPAREN, CHECK_OK); 29063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Statement* body = ParseStatement(NULL, CHECK_OK); 29083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* body_block = factory()->NewBlock(NULL, 3, false); 29093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Assignment* assignment = factory()->NewAssignment( 29103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); 29113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Statement* assignment_statement = 29123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewExpressionStatement(assignment); 29133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch body_block->AddStatement(variable_statement); 29143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch body_block->AddStatement(assignment_statement); 29153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch body_block->AddStatement(body); 29163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch loop->Initialize(temp_proxy, enumerable, body_block); 29173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_ = saved_scope; 29183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for_scope->set_end_position(scanner().location().end_pos); 29193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for_scope = for_scope->FinalizeBlockScope(); 29203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch body_block->set_block_scope(for_scope); 29213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Parsed for-in loop w/ let declaration. 29223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return loop; 2923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 29253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch init = variable_statement; 29263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* expression = ParseExpression(false, CHECK_OK); 2929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() == Token::IN) { 2930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Signal a reference error if the expression is an invalid 2931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // left-hand side expression. We could report this as a syntax 2932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // error here but for compatibility with JSC we choose to report 2933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the error at runtime. 2934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (expression == NULL || !expression->IsValidLeftHandSide()) { 293544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> type = 293644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()->invalid_lhs_in_for_in_symbol(); 2937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expression = NewThrowReferenceError(type); 2938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 29393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ForInStatement* loop = factory()->NewForInStatement(labels); 29403e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Target target(&this->target_stack_, loop); 2941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::IN, CHECK_OK); 2943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* enumerable = ParseExpression(true, CHECK_OK); 2944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 2945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* body = ParseStatement(NULL, CHECK_OK); 2947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (loop) loop->Initialize(expression, enumerable, body); 29483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_ = saved_scope; 29493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for_scope->set_end_position(scanner().location().end_pos); 29503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for_scope = for_scope->FinalizeBlockScope(); 29513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(for_scope == NULL); 2952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parsed for-in loop. 2953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return loop; 2954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 29563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch init = factory()->NewExpressionStatement(expression); 2957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Standard 'for' loop 29623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ForStatement* loop = factory()->NewForStatement(labels); 29633e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Target target(&this->target_stack_, loop); 2964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parsed initializer at this point. 2966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::SEMICOLON, CHECK_OK); 2967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* cond = NULL; 2969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() != Token::SEMICOLON) { 2970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block cond = ParseExpression(true, CHECK_OK); 2971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::SEMICOLON, CHECK_OK); 2973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* next = NULL; 2975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() != Token::RPAREN) { 2976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* exp = ParseExpression(true, CHECK_OK); 29773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch next = factory()->NewExpressionStatement(exp); 2978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 2980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Statement* body = ParseStatement(NULL, CHECK_OK); 29823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_ = saved_scope; 29833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for_scope->set_end_position(scanner().location().end_pos); 29843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for_scope = for_scope->FinalizeBlockScope(); 29853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (for_scope != NULL) { 29863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Rewrite a for statement of the form 29873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 29883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // for (let x = i; c; n) b 29893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 29903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // into 29913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 29923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // { 29933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // let x = i; 29943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // for (; c; n) b 29953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // } 29963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(init != NULL); 29973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Block* result = factory()->NewBlock(NULL, 2, false); 29983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result->AddStatement(init); 29993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result->AddStatement(loop); 30003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result->set_block_scope(for_scope); 30013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (loop) loop->Initialize(NULL, cond, next, body); 30023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return result; 30033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 30043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (loop) loop->Initialize(init, cond, next, body); 30053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return loop; 30063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Precedence = 1 3011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseExpression(bool accept_IN, bool* ok) { 3012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Expression :: 3013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // AssignmentExpression 3014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Expression ',' AssignmentExpression 3015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); 3017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (peek() == Token::COMMA) { 3018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::COMMA, CHECK_OK); 301980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int position = scanner().location().beg_pos; 3020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 30213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = 30223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewBinaryOperation(Token::COMMA, result, right, position); 3023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 3025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Precedence = 2 3029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { 3030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // AssignmentExpression :: 3031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ConditionalExpression 3032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // LeftHandSideExpression AssignmentOperator AssignmentExpression 3033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->Enter(); 3035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); 3036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Token::IsAssignmentOp(peek())) { 303880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->Leave(); 3039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parsed conditional expression only (no assignment). 3040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return expression; 3041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Signal a reference error if the expression is an invalid left-hand 3044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // side expression. We could report this as a syntax error here but 3045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for compatibility with JSC we choose to report the error at 3046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // runtime. 3047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (expression == NULL || !expression->IsValidLeftHandSide()) { 304844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> type = 304944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()->invalid_lhs_in_assignment_symbol(); 3050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expression = NewThrowReferenceError(type); 3051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!top_scope_->is_classic_mode()) { 30541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Assignment to eval or arguments is disallowed in strict mode. 30551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); 30561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 30573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkAsLValue(expression); 30581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value op = Next(); // Get assignment operator. 3060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos = scanner().location().beg_pos; 3061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 3062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // TODO(1231235): We try to estimate the set of properties set by 3064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // constructors. We define a new property whenever there is an 3065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // assignment to a property of 'this'. We should probably only add 3066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // properties if we haven't seen them before. Otherwise we'll 3067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // probably overestimate the number of properties. 3068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Property* property = expression ? expression->AsProperty() : NULL; 3069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (op == Token::ASSIGN && 3070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block property != NULL && 3071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block property->obj()->AsVariableProxy() != NULL && 3072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block property->obj()->AsVariableProxy()->is_this()) { 30733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current_function_state_->AddProperty(); 3074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // If we assign a function literal to a property we pretenure the 30778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // literal so it can be added as a constant function property. 30788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (property != NULL && right->AsFunctionLiteral() != NULL) { 30793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch right->AsFunctionLiteral()->set_pretenure(); 30808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 30818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 308280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) { 308380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Check if the right hand side is a call to avoid inferring a 308480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // name if we're dealing with "a = function(){...}();"-like 308580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // expression. 308680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if ((op == Token::INIT_VAR 308780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen || op == Token::INIT_CONST 308880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen || op == Token::ASSIGN) 30893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch && (right->AsCall() == NULL && right->AsCallNew() == NULL)) { 309080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen fni_->Infer(); 309169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 309269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch fni_->RemoveLastFunction(); 309380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 309480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen fni_->Leave(); 309580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 309680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 30973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewAssignment(op, expression, right, pos); 3098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Precedence = 3 3102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { 3103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ConditionalExpression :: 3104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // LogicalOrExpression 3105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 3106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We start using the binary expression parser for prec >= 4 only! 3108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); 3109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() != Token::CONDITIONAL) return expression; 3110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::CONDITIONAL); 3111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // In parsing the first assignment expression in conditional 3112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // expressions we always accept the 'in' keyword; see ECMA-262, 3113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // section 11.12, page 58. 31147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch int left_position = scanner().peek_location().beg_pos; 3115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* left = ParseAssignmentExpression(true, CHECK_OK); 3116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::COLON, CHECK_OK); 31177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch int right_position = scanner().peek_location().beg_pos; 3118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 31193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewConditional( 31203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expression, left, right, left_position, right_position); 3121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int Precedence(Token::Value tok, bool accept_IN) { 3125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (tok == Token::IN && !accept_IN) 3126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0; // 0 precedence will terminate binary expression parsing 3127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Token::Precedence(tok); 3129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Precedence >= 4 3133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { 3134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(prec >= 4); 3135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* x = ParseUnaryExpression(CHECK_OK); 3136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 3137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prec1 >= 4 3138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (Precedence(peek(), accept_IN) == prec1) { 3139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value op = Next(); 314080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int position = scanner().location().beg_pos; 3141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); 3142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute some expressions involving only number literals. 3144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() && 3145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) { 3146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block double x_val = x->AsLiteral()->handle()->Number(); 3147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block double y_val = y->AsLiteral()->handle()->Number(); 3148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (op) { 3150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::ADD: 31513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewNumberLiteral(x_val + y_val); 3152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 3153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::SUB: 31543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewNumberLiteral(x_val - y_val); 3155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 3156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::MUL: 31573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewNumberLiteral(x_val * y_val); 3158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 3159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::DIV: 31603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewNumberLiteral(x_val / y_val); 3161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 31623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::BIT_OR: { 31633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); 31643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewNumberLiteral(value); 3165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 31663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 31673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::BIT_AND: { 31683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); 31693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewNumberLiteral(value); 3170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 31713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 31723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::BIT_XOR: { 31733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); 31743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewNumberLiteral(value); 3175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 31763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::SHL: { 3178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); 31793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewNumberLiteral(value); 3180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 3181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::SHR: { 3183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t shift = DoubleToInt32(y_val) & 0x1f; 3184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t value = DoubleToUint32(x_val) >> shift; 31853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewNumberLiteral(value); 3186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 3187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::SAR: { 3189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t shift = DoubleToInt32(y_val) & 0x1f; 3190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); 31913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewNumberLiteral(value); 3192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 3193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 3195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For now we distinguish between comparisons and other binary 3200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // operations. (We could combine the two and get rid of this 320180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // code and AST node eventually.) 3202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Token::IsCompareOp(op)) { 3203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We have a comparison. 3204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value cmp = op; 3205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (op) { 3206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::NE: cmp = Token::EQ; break; 3207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; 3208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: break; 3209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 32103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewCompareOperation(cmp, x, y, position); 3211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (cmp != op) { 3212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The comparison was negated - add a NOT. 32133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewUnaryOperation(Token::NOT, x, position); 3214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 3217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We have a "normal" binary operation. 32183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch x = factory()->NewBinaryOperation(op, x, y, position); 3219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return x; 3223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseUnaryExpression(bool* ok) { 3227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // UnaryExpression :: 3228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // PostfixExpression 3229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'delete' UnaryExpression 3230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'void' UnaryExpression 3231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'typeof' UnaryExpression 3232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '++' UnaryExpression 3233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '--' UnaryExpression 3234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '+' UnaryExpression 3235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '-' UnaryExpression 3236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '~' UnaryExpression 3237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '!' UnaryExpression 3238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value op = peek(); 3240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Token::IsUnaryOp(op)) { 3241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block op = Next(); 3242257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int position = scanner().location().beg_pos; 3243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* expression = ParseUnaryExpression(CHECK_OK); 3244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (expression != NULL && (expression->AsLiteral() != NULL)) { 32463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Object> literal = expression->AsLiteral()->handle(); 32473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (op == Token::NOT) { 32483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Convert the literal to a boolean condition and negate it. 32493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool condition = literal->ToBoolean()->IsTrue(); 32503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Object> result(isolate()->heap()->ToBoolean(!condition)); 32513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewLiteral(result); 32523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (literal->IsNumber()) { 32533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Compute some expressions involving only number literals. 32543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch double value = literal->Number(); 32553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch switch (op) { 32563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::ADD: 32573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return expression; 32583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::SUB: 32593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewNumberLiteral(-value); 32603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::BIT_NOT: 32613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewNumberLiteral(~DoubleToInt32(value)); 32623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch default: 32633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 32643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3268e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // "delete identifier" is a syntax error in strict mode. 32693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (op == Token::DELETE && !top_scope_->is_classic_mode()) { 3270e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch VariableProxy* operand = expression->AsVariableProxy(); 3271e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (operand != NULL && !operand->is_this()) { 3272e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ReportMessage("strict_delete", Vector<const char*>::empty()); 3273e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *ok = false; 3274e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return NULL; 3275e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 3276e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 3277e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 32783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewUnaryOperation(op, expression, position); 3279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (Token::IsCountOp(op)) { 3281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block op = Next(); 3282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* expression = ParseUnaryExpression(CHECK_OK); 3283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Signal a reference error if the expression is an invalid 3284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // left-hand side expression. We could report this as a syntax 3285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // error here but for compatibility with JSC we choose to report the 3286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // error at runtime. 3287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (expression == NULL || !expression->IsValidLeftHandSide()) { 328844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> type = 328944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); 3290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expression = NewThrowReferenceError(type); 3291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 32921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 32933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!top_scope_->is_classic_mode()) { 32941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Prefix expression operand in strict mode may not be eval or arguments. 32951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); 32961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 32973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkAsLValue(expression); 32981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 329980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int position = scanner().location().beg_pos; 33003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewCountOperation(op, 33013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch true /* prefix */, 33023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expression, 33033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch position); 3304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 3306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ParsePostfixExpression(ok); 3307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParsePostfixExpression(bool* ok) { 3312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // PostfixExpression :: 3313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // LeftHandSideExpression ('++' | '--')? 3314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* expression = ParseLeftHandSideExpression(CHECK_OK); 33163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!scanner().HasAnyLineTerminatorBeforeNext() && 3317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Token::IsCountOp(peek())) { 3318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Signal a reference error if the expression is an invalid 3319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // left-hand side expression. We could report this as a syntax 3320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // error here but for compatibility with JSC we choose to report the 3321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // error at runtime. 3322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (expression == NULL || !expression->IsValidLeftHandSide()) { 332344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> type = 332444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); 3325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expression = NewThrowReferenceError(type); 3326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 33271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 33283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!top_scope_->is_classic_mode()) { 33291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Postfix expression operand in strict mode may not be eval or arguments. 33301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); 33311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 33323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkAsLValue(expression); 33331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value next = Next(); 333580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int position = scanner().location().beg_pos; 33368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch expression = 33373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewCountOperation(next, 33383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch false /* postfix */, 33393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expression, 33403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch position); 3341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return expression; 3343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseLeftHandSideExpression(bool* ok) { 3347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // LeftHandSideExpression :: 3348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // (NewExpression | MemberExpression) ... 3349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* result; 3351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() == Token::NEW) { 3352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParseNewExpression(CHECK_OK); 3353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 3354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParseMemberExpression(CHECK_OK); 3355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 3358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (peek()) { 3359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::LBRACK: { 3360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::LBRACK); 3361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos = scanner().location().beg_pos; 3362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* index = ParseExpression(true, CHECK_OK); 33633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewProperty(result, index, pos); 3364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RBRACK, CHECK_OK); 3365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::LPAREN: { 33693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int pos; 33703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (scanner().current_token() == Token::IDENTIFIER) { 33713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // For call of an identifier we want to report position of 33723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the identifier as position of the call in the stack trace. 33733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pos = scanner().location().beg_pos; 33743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 33753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // For other kinds of calls we record position of the parenthesis as 33763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // position of the call. Note that this is extremely important for 33773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // expressions of the form function(){...}() for which call position 33783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // should not point to the closing brace otherwise it will intersect 33793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // with positions recorded for function literal and confuse debugger. 33803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pos = scanner().peek_location().beg_pos; 33813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 3383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Keep track of eval() calls since they disable all local variable 3385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // optimizations. 3386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The calls that need special treatment are the 33873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // direct eval calls. These calls are all of the form eval(...), with 33883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // no explicit receiver. 3389b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // These calls are marked as potentially direct eval calls. Whether 3390b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // they are actually direct calls to eval is determined at run time. 33913e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu VariableProxy* callee = result->AsVariableProxy(); 339244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (callee != NULL && 339344f0eee88ff00398ff7f715fab053374d808c90dSteve Block callee->IsVariable(isolate()->factory()->eval_symbol())) { 33943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_->DeclarationScope()->RecordEvalCall(); 3395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 33963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewCall(result, args, pos); 3397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::PERIOD: { 3401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::PERIOD); 3402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos = scanner().location().beg_pos; 3403bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Handle<String> name = ParseIdentifierName(CHECK_OK); 34043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = 34053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewProperty(result, factory()->NewLiteral(name), pos); 340680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->PushLiteralName(name); 3407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 3411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 3412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { 3418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // NewExpression :: 3419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ('new')+ MemberExpression 3420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The grammar for new expressions is pretty warped. The keyword 3422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'new' can either be a part of the new expression (where it isn't 3423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // followed by an argument list) or a part of the member expression, 3424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // where it must be followed by an argument list. To accommodate 3425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // this, we parse the 'new' keywords greedily and keep track of how 3426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // many we have parsed. This information is then passed on to the 3427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // member expression parser, which is only allowed to match argument 3428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // lists as long as it has 'new' prefixes left 3429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::NEW, CHECK_OK); 3430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PositionStack::Element pos(stack, scanner().location().beg_pos); 3431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* result; 3433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() == Token::NEW) { 3434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParseNewPrefix(stack, CHECK_OK); 3435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 3436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); 3437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!stack->is_empty()) { 3440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int last = stack->pop(); 34413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewCallNew( 34423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result, new(zone()) ZoneList<Expression*>(0), last); 3443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 3445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseNewExpression(bool* ok) { 3449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PositionStack stack(ok); 3450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ParseNewPrefix(&stack, ok); 3451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseMemberExpression(bool* ok) { 3455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ParseMemberWithNewPrefixesExpression(NULL, ok); 3456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, 3460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* ok) { 3461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // MemberExpression :: 3462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // (PrimaryExpression | FunctionLiteral) 3463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ('[' Expression ']' | '.' Identifier | Arguments)* 3464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parse the initial primary or function expression. 3466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* result = NULL; 3467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() == Token::FUNCTION) { 3468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::FUNCTION, CHECK_OK); 3469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int function_token_position = scanner().location().beg_pos; 3470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name; 34713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_strict_reserved_name = false; 34721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (peek_any_identifier()) { 34733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 34743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_OK); 34751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 34763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch FunctionLiteral::Type type = name.is_null() 34773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ? FunctionLiteral::ANONYMOUS_EXPRESSION 34783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : FunctionLiteral::NAMED_EXPRESSION; 34793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result = ParseFunctionLiteral(name, 34803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch is_strict_reserved_name, 34813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch function_token_position, 34823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch type, 34833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_OK); 3484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 3485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParsePrimaryExpression(CHECK_OK); 3486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 3489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (peek()) { 3490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::LBRACK: { 3491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::LBRACK); 3492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos = scanner().location().beg_pos; 3493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* index = ParseExpression(true, CHECK_OK); 34943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewProperty(result, index, pos); 34953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (fni_ != NULL) { 34963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (index->IsPropertyName()) { 34973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); 34983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 34993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fni_->PushLiteralName( 35003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate()->factory()->anonymous_function_symbol()); 35013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 35023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RBRACK, CHECK_OK); 3504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::PERIOD: { 3507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::PERIOD); 3508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos = scanner().location().beg_pos; 3509bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Handle<String> name = ParseIdentifierName(CHECK_OK); 35103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = 35113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewProperty(result, factory()->NewLiteral(name), pos); 351280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->PushLiteralName(name); 3513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::LPAREN: { 3516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((stack == NULL) || stack->is_empty()) return result; 3517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Consume one of the new prefixes (already parsed). 3518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 3519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int last = stack->pop(); 35203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewCallNew(result, args, last); 3521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 3524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 3525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockDebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { 3531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 3532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // contexts this is used as a statement which invokes the debugger as i a 3533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // break point is present. 3534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // DebuggerStatement :: 3535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'debugger' ';' 3536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::DEBUGGER, CHECK_OK); 3538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectSemicolon(CHECK_OK); 35393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewDebuggerStatement(); 3540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Parser::ReportUnexpectedToken(Token::Value token) { 3544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We don't report stack overflows here, to avoid increasing the 3545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // stack depth even further. Instead we report it after parsing is 35464515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // over, in ParseProgram/ParseJson. 3547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (token == Token::ILLEGAL && stack_overflow_) return; 3548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Four of the tokens are treated specially 3549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (token) { 3550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Token::EOS: 3551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return ReportMessage("unexpected_eos", Vector<const char*>::empty()); 3552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Token::NUMBER: 3553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return ReportMessage("unexpected_token_number", 3554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Vector<const char*>::empty()); 3555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Token::STRING: 3556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return ReportMessage("unexpected_token_string", 3557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Vector<const char*>::empty()); 3558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Token::IDENTIFIER: 3559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return ReportMessage("unexpected_token_identifier", 3560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Vector<const char*>::empty()); 35611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block case Token::FUTURE_RESERVED_WORD: 35623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ReportMessage("unexpected_reserved", 35633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Vector<const char*>::empty()); 35643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::FUTURE_STRICT_RESERVED_WORD: 35653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ReportMessage(top_scope_->is_classic_mode() ? 35663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "unexpected_token_identifier" : 35673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "unexpected_strict_reserved", 35681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Vector<const char*>::empty()); 3569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch default: 3570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* name = Token::String(token); 3571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(name != NULL); 3572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); 3573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3577ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarkevoid Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { 3578589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); 3579ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke const char* element[1] = { *name_string }; 3580ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke ReportMessage("invalid_preparser_data", 3581ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke Vector<const char*>(element, 1)); 3582ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke *ok = false; 3583ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke} 3584ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke 3585ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke 3586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParsePrimaryExpression(bool* ok) { 3587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // PrimaryExpression :: 3588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'this' 3589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'null' 3590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'true' 3591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'false' 3592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Identifier 3593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Number 3594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // String 3595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ArrayLiteral 3596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ObjectLiteral 3597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // RegExpLiteral 3598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '(' Expression ')' 3599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* result = NULL; 3601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (peek()) { 3602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::THIS: { 3603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::THIS); 36043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewVariableProxy(top_scope_->receiver()); 3605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::NULL_LITERAL: 3609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::NULL_LITERAL); 36103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewLiteral(isolate()->factory()->null_value()); 3611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::TRUE_LITERAL: 3614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::TRUE_LITERAL); 36153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewLiteral(isolate()->factory()->true_value()); 3616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::FALSE_LITERAL: 3619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::FALSE_LITERAL); 36203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewLiteral(isolate()->factory()->false_value()); 3621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block case Token::IDENTIFIER: 36243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::FUTURE_STRICT_RESERVED_WORD: { 3625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name = ParseIdentifier(CHECK_OK); 362680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->PushVariableName(name); 36273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The name may refer to a module instance object, so its type is unknown. 36283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 36293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_interface_details) 36303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("# Variable %s ", name->ToAsciiArray()); 36313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 36323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Interface* interface = Interface::NewUnknown(); 36333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = top_scope_->NewUnresolved( 36343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory(), name, scanner().location().beg_pos, interface); 3635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::NUMBER: { 3639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::NUMBER); 36409fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block ASSERT(scanner().is_literal_ascii()); 36418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double value = StringToDouble(isolate()->unicode_cache(), 36428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch scanner().literal_ascii_string(), 36439fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block ALLOW_HEX | ALLOW_OCTALS); 36443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewNumberLiteral(value); 3645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::STRING: { 3649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::STRING); 36509ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick Handle<String> symbol = GetSymbol(CHECK_OK); 36513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = factory()->NewLiteral(symbol); 365280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->PushLiteralName(symbol); 3653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::ASSIGN_DIV: 3657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParseRegExpLiteral(true, CHECK_OK); 3658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::DIV: 3661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParseRegExpLiteral(false, CHECK_OK); 3662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::LBRACK: 3665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParseArrayLiteral(CHECK_OK); 3666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::LBRACE: 3669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParseObjectLiteral(CHECK_OK); 3670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::LPAREN: 3673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::LPAREN); 3674b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Heuristically try to detect immediately called functions before 3675b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // seeing the call parentheses. 3676b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch parenthesized_function_ = (peek() == Token::FUNCTION); 3677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParseExpression(true, CHECK_OK); 3678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 3679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::MOD: 3682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (allow_natives_syntax_ || extension_ != NULL) { 3683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParseV8Intrinsic(CHECK_OK); 3684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 3685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we're not allowing special syntax we fall-through to the 3687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // default case. 3688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: { 3690bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Token::Value tok = Next(); 3691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportUnexpectedToken(tok); 3692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *ok = false; 3693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 3694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 3698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37014515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid Parser::BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* values, 37024515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Handle<FixedArray> literals, 37034515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke bool* is_simple, 37044515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int* depth) { 37054515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Fill in the literals. 37064515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Accumulate output values in local variables. 37074515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke bool is_simple_acc = true; 37084515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int depth_acc = 1; 37094515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke for (int i = 0; i < values->length(); i++) { 37104515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); 37114515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (m_literal != NULL && m_literal->depth() >= depth_acc) { 37124515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke depth_acc = m_literal->depth() + 1; 37134515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 37144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); 37154515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (boilerplate_value->IsUndefined()) { 37164515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke literals->set_the_hole(i); 37174515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke is_simple_acc = false; 37184515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } else { 37194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke literals->set(i, *boilerplate_value); 37204515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 37214515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 37224515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 37234515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke *is_simple = is_simple_acc; 37244515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke *depth = depth_acc; 37254515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 37264515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 37274515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 3728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseArrayLiteral(bool* ok) { 3729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ArrayLiteral :: 3730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '[' Expression? (',' Expression?)* ']' 3731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3732257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4); 3733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LBRACK, CHECK_OK); 3734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (peek() != Token::RBRACK) { 3735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* elem; 3736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() == Token::COMMA) { 3737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elem = GetLiteralTheHole(); 3738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 3739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elem = ParseAssignmentExpression(true, CHECK_OK); 3740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 37413e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu values->Add(elem); 3742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() != Token::RBRACK) { 3743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::COMMA, CHECK_OK); 3744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RBRACK, CHECK_OK); 3747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the scope information before the pre-parsing bailout. 37493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int literal_index = current_function_state_->NextMaterializedLiteralIndex(); 3750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Allocate a fixed array to hold all the object literals. 37523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FixedArray> object_literals = 375344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()->NewFixedArray(values->length(), TENURED); 37543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FixedDoubleArray> double_literals; 37553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS; 37563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool has_only_undefined_values = true; 3757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill in the literals. 3759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_simple = true; 3760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int depth = 1; 37613e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu for (int i = 0, n = values->length(); i < n; i++) { 37623e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); 3763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (m_literal != NULL && m_literal->depth() + 1 > depth) { 3764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block depth = m_literal->depth() + 1; 3765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 37663e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); 3767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (boilerplate_value->IsUndefined()) { 37683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object_literals->set_the_hole(i); 37693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (elements_kind == FAST_DOUBLE_ELEMENTS) { 37703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_literals->set_the_hole(i); 37713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_simple = false; 3773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 37743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Examine each literal element, and adjust the ElementsKind if the 37753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // literal element is not of a type that can be stored in the current 37763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ElementsKind. Start with FAST_SMI_ONLY_ELEMENTS, and transition to 37773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // FAST_DOUBLE_ELEMENTS and FAST_ELEMENTS as necessary. Always remember 37783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the tagged value, no matter what the ElementsKind is in case we 37793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ultimately end up in FAST_ELEMENTS. 37803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch has_only_undefined_values = false; 37813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object_literals->set(i, *boilerplate_value); 37823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { 37833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Smi only elements. Notice if a transition to FAST_DOUBLE_ELEMENTS or 37843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // FAST_ELEMENTS is required. 37853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!boilerplate_value->IsSmi()) { 37863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (boilerplate_value->IsNumber() && FLAG_smi_only_arrays) { 37873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Allocate a double array on the FAST_DOUBLE_ELEMENTS transition to 37883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // avoid over-allocating in TENURED space. 37893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_literals = isolate()->factory()->NewFixedDoubleArray( 37903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch values->length(), TENURED); 37913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Copy the contents of the FAST_SMI_ONLY_ELEMENT array to the 37923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // FAST_DOUBLE_ELEMENTS array so that they are in sync. 37933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int j = 0; j < i; ++j) { 37943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* smi_value = object_literals->get(j); 37953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_value->IsTheHole()) { 37963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_literals->set_the_hole(j); 37973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 37983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_literals->set(j, Smi::cast(smi_value)->value()); 37993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_literals->set(i, boilerplate_value->Number()); 38023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elements_kind = FAST_DOUBLE_ELEMENTS; 38033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 38043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elements_kind = FAST_ELEMENTS; 38053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (elements_kind == FAST_DOUBLE_ELEMENTS) { 38083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Continue to store double values in to FAST_DOUBLE_ELEMENTS arrays 38093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // until the first value is seen that can't be stored as a double. 38103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (boilerplate_value->IsNumber()) { 38113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_literals->set(i, boilerplate_value->Number()); 38123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 38133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elements_kind = FAST_ELEMENTS; 38143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Very small array literals that don't have a concrete hint about their type 38203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // from a constant value should default to the slow case to avoid lots of 38213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // elements transitions on really small objects. 38223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (has_only_undefined_values && values->length() <= 2) { 38233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elements_kind = FAST_ELEMENTS; 38243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3826756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Simple and shallow arrays can be lazily copied, we transform the 3827756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // elements array to a copy-on-write array. 38283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (is_simple && depth == 1 && values->length() > 0 && 38293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elements_kind != FAST_DOUBLE_ELEMENTS) { 38303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object_literals->set_map(isolate()->heap()->fixed_cow_array_map()); 3831756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 3832756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 38333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FixedArrayBase> element_values = elements_kind == FAST_DOUBLE_ELEMENTS 38343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? Handle<FixedArrayBase>(double_literals) 38353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : Handle<FixedArrayBase>(object_literals); 38363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Remember both the literal's constant values as well as the ElementsKind 38383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // in a 2-element FixedArray. 38393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FixedArray> literals = 38403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->factory()->NewFixedArray(2, TENURED); 38413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch literals->set(0, Smi::FromInt(elements_kind)); 38433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch literals->set(1, *element_values); 38443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewArrayLiteral( 38463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch literals, values, literal_index, is_simple, depth); 3847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { 3851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return property != NULL && 3852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block property->kind() != ObjectLiteral::Property::PROTOTYPE; 3853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool CompileTimeValue::IsCompileTimeValue(Expression* expression) { 3857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (expression->AsLiteral() != NULL) return true; 3858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MaterializedLiteral* lit = expression->AsMaterializedLiteral(); 3859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return lit != NULL && lit->is_simple(); 3860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3862756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3863756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickbool CompileTimeValue::ArrayLiteralElementNeedsInitialization( 3864756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Expression* value) { 3865756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // If value is a literal the property value is already set in the 3866756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // boilerplate object. 3867756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (value->AsLiteral() != NULL) return false; 3868756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // If value is a materialized literal the property value is already set 3869756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // in the boilerplate object if it is simple. 3870756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (CompileTimeValue::IsCompileTimeValue(value)) return false; 3871756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return true; 3872756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 3873756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3874756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompileTimeValue::GetValue(Expression* expression) { 3876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCompileTimeValue(expression)); 387744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<FixedArray> result = FACTORY->NewFixedArray(2, TENURED); 3878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ObjectLiteral* object_literal = expression->AsObjectLiteral(); 3879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object_literal != NULL) { 3880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(object_literal->is_simple()); 38816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (object_literal->fast_elements()) { 38826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS)); 38836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 38846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS)); 38856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 3886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->set(kElementsSlot, *object_literal->constant_properties()); 3887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 3888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArrayLiteral* array_literal = expression->AsArrayLiteral(); 3889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(array_literal != NULL && array_literal->is_simple()); 3890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL)); 3891e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke result->set(kElementsSlot, *array_literal->constant_elements()); 3892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 3894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCompileTimeValue::Type CompileTimeValue::GetType(Handle<FixedArray> value) { 3898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Smi* type_value = Smi::cast(value->get(kTypeSlot)); 3899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<Type>(type_value->value()); 3900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { 3904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); 3905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Parser::GetBoilerplateValue(Expression* expression) { 3909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (expression->AsLiteral() != NULL) { 3910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return expression->AsLiteral()->handle(); 3911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (CompileTimeValue::IsCompileTimeValue(expression)) { 3913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return CompileTimeValue::GetValue(expression); 3914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 391544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->factory()->undefined_value(); 3916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Validation per 11.1.5 Object Initialiser 39191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockclass ObjectLiteralPropertyChecker { 39201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public: 39213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) : 39223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch props_(Literal::Match), 39231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block parser_(parser), 39243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch language_mode_(language_mode) { 39251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 39261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 39271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void CheckProperty( 39281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ObjectLiteral::Property* property, 39291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Scanner::Location loc, 39301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool* ok); 39311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 39321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private: 39331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block enum PropertyKind { 39341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block kGetAccessor = 0x01, 39351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block kSetAccessor = 0x02, 39361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block kAccessor = kGetAccessor | kSetAccessor, 39371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block kData = 0x04 39381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block }; 39391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 39401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static intptr_t GetPropertyKind(ObjectLiteral::Property* property) { 39411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block switch (property->kind()) { 39421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block case ObjectLiteral::Property::GETTER: 39431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return kGetAccessor; 39441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block case ObjectLiteral::Property::SETTER: 39451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return kSetAccessor; 39461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block default: 39471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return kData; 39481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 39491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 39501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 39513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HashMap props_; 39521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Parser* parser_; 39533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LanguageMode language_mode_; 39541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 39551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 39561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 39571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid ObjectLiteralPropertyChecker::CheckProperty( 39581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ObjectLiteral::Property* property, 39591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Scanner::Location loc, 39601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool* ok) { 39611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ASSERT(property != NULL); 39623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Literal* literal = property->key(); 39633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HashMap::Entry* entry = props_.Lookup(literal, literal->Hash(), true); 39641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block intptr_t prev = reinterpret_cast<intptr_t> (entry->value); 39651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block intptr_t curr = GetPropertyKind(property); 39661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 39673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Duplicate data properties are illegal in strict or extended mode. 39683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (language_mode_ != CLASSIC_MODE && (curr & prev & kData) != 0) { 39691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block parser_->ReportMessageAt(loc, "strict_duplicate_property", 39701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Vector<const char*>::empty()); 39711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 39721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return; 39731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 39741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Data property conflicting with an accessor. 39751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (((curr & kData) && (prev & kAccessor)) || 39761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ((prev & kData) && (curr & kAccessor))) { 39771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block parser_->ReportMessageAt(loc, "accessor_data_property", 39781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Vector<const char*>::empty()); 39791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 39801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return; 39811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 39821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Two accessors of the same type conflicting 39831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if ((curr & prev & kAccessor) != 0) { 39841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block parser_->ReportMessageAt(loc, "accessor_get_set", 39851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Vector<const char*>::empty()); 39861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 39871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return; 39881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 39891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 39901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Update map 39911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block entry->value = reinterpret_cast<void*> (prev | curr); 39921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = true; 39931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 39941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39964515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid Parser::BuildObjectLiteralConstantProperties( 39974515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ZoneList<ObjectLiteral::Property*>* properties, 39984515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Handle<FixedArray> constant_properties, 39994515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke bool* is_simple, 40006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool* fast_elements, 40014515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int* depth) { 40024515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int position = 0; 40034515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Accumulate the value in local variables and store it at the end. 40044515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke bool is_simple_acc = true; 40054515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int depth_acc = 1; 40066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block uint32_t max_element_index = 0; 40076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block uint32_t elements = 0; 40084515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke for (int i = 0; i < properties->length(); i++) { 40094515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ObjectLiteral::Property* property = properties->at(i); 40104515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (!IsBoilerplateProperty(property)) { 40114515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke is_simple_acc = false; 40124515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke continue; 40134515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 40144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); 40154515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (m_literal != NULL && m_literal->depth() >= depth_acc) { 40164515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke depth_acc = m_literal->depth() + 1; 40174515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 40184515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 40194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined 40204515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // value for COMPUTED properties, the real value is filled in at 40214515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // runtime. The enumeration order is maintained. 40224515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Handle<Object> key = property->key()->handle(); 40234515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Handle<Object> value = GetBoilerplateValue(property->value()); 40244515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke is_simple_acc = is_simple_acc && !value->IsUndefined(); 40254515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 40266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Keep track of the number of elements in the object literal and 40276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // the largest element index. If the largest element index is 40286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // much larger than the number of elements, creating an object 40296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // literal with fast elements will be a waste of space. 40306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block uint32_t element_index = 0; 40316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (key->IsString() 40326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block && Handle<String>::cast(key)->AsArrayIndex(&element_index) 40336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block && element_index > max_element_index) { 40346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block max_element_index = element_index; 40356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block elements++; 40366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else if (key->IsSmi()) { 40376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int key_value = Smi::cast(*key)->value(); 40386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (key_value > 0 40396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block && static_cast<uint32_t>(key_value) > max_element_index) { 40406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block max_element_index = key_value; 40416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 40426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block elements++; 40436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 40446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 40454515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Add name, value pair to the fixed array. 40464515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke constant_properties->set(position++, *key); 40474515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke constant_properties->set(position++, *value); 40484515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 40496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block *fast_elements = 40506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block (max_element_index <= 32) || ((2 * elements) >= max_element_index); 40514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke *is_simple = is_simple_acc; 40524515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke *depth = depth_acc; 40534515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 40544515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 40554515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 4056bb769b257e753aafcbd96767abb2abc645eaa20cBen MurdochObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, 4057bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch bool* ok) { 4058bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // Special handling of getter and setter syntax: 4059bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 4060bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // We have already read the "get" or "set" keyword. 4061bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Token::Value next = Next(); 40629fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block bool is_keyword = Token::IsKeyword(next); 40639fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block if (next == Token::IDENTIFIER || next == Token::NUMBER || 40641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block next == Token::FUTURE_RESERVED_WORD || 40653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch next == Token::FUTURE_STRICT_RESERVED_WORD || 40669fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block next == Token::STRING || is_keyword) { 40679fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Handle<String> name; 40689fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block if (is_keyword) { 406944f0eee88ff00398ff7f715fab053374d808c90dSteve Block name = isolate_->factory()->LookupAsciiSymbol(Token::String(next)); 40709fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block } else { 40719fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block name = GetSymbol(CHECK_OK); 40729fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block } 4073bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch FunctionLiteral* value = 4074bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch ParseFunctionLiteral(name, 40751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block false, // reserved words are allowed here 4076bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch RelocInfo::kNoPosition, 40773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch FunctionLiteral::ANONYMOUS_EXPRESSION, 4078bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch CHECK_OK); 40793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Allow any number of parameters for compatibilty with JSC. 40809fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block // Specification only allows zero parameters for get and one for set. 40813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewObjectLiteralProperty(is_getter, value); 4082bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } else { 4083bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch ReportUnexpectedToken(next); 4084bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch *ok = false; 4085bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch return NULL; 4086bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 4087bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4088bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4089bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseObjectLiteral(bool* ok) { 4091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ObjectLiteral :: 4092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '{' ( 4093bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // ((IdentifierName | String | Number) ':' AssignmentExpression) 4094bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 4095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // )*[','] '}' 4096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40973e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu ZoneList<ObjectLiteral::Property*>* properties = 4098257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch new(zone()) ZoneList<ObjectLiteral::Property*>(4); 4099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int number_of_boilerplate_properties = 0; 410044f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool has_function = false; 4101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 41023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectLiteralPropertyChecker checker(this, top_scope_->language_mode()); 41031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LBRACE, CHECK_OK); 41051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (peek() != Token::RBRACE) { 410780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->Enter(); 410880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 4109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Literal* key = NULL; 4110bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Token::Value next = peek(); 41111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 41121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Location of the property name token 41131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Scanner::Location loc = scanner().peek_location(); 41141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4115bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch switch (next) { 41161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block case Token::FUTURE_RESERVED_WORD: 41173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::FUTURE_STRICT_RESERVED_WORD: 4118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::IDENTIFIER: { 4119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_getter = false; 4120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_setter = false; 4121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> id = 41223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 412380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->PushLiteralName(id); 412480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 4125bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if ((is_getter || is_setter) && peek() != Token::COLON) { 41261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Update loc to point to the identifier 41271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block loc = scanner().peek_location(); 4128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ObjectLiteral::Property* property = 4129bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch ParseObjectLiteralGetSet(is_getter, CHECK_OK); 4130bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (IsBoilerplateProperty(property)) { 4131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block number_of_boilerplate_properties++; 4132bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 41331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Validate the property. 41341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block checker.CheckProperty(property, loc, CHECK_OK); 41353e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu properties->Add(property); 4136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 413780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 413880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) { 413980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen fni_->Infer(); 414080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen fni_->Leave(); 414180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 4142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; // restart the while 4143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4144bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // Failed to parse as get/set property, so it's just a property 4145bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // called "get" or "set". 41463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key = factory()->NewLiteral(id); 4147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 4148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::STRING: { 4150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::STRING); 41519ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick Handle<String> string = GetSymbol(CHECK_OK); 415280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) fni_->PushLiteralName(string); 4153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t index; 4154756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (!string.is_null() && string->AsArrayIndex(&index)) { 41553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key = factory()->NewNumberLiteral(index); 4156bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch break; 4157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 41583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key = factory()->NewLiteral(string); 4159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 4160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case Token::NUMBER: { 4162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Consume(Token::NUMBER); 41639fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block ASSERT(scanner().is_literal_ascii()); 41648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double value = StringToDouble(isolate()->unicode_cache(), 41658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch scanner().literal_ascii_string(), 41669fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block ALLOW_HEX | ALLOW_OCTALS); 41673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key = factory()->NewNumberLiteral(value); 4168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 4169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 4171bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (Token::IsKeyword(next)) { 4172bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Consume(next); 41739ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick Handle<String> string = GetSymbol(CHECK_OK); 41743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key = factory()->NewLiteral(string); 4175bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } else { 4176bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // Unexpected token. 4177bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Token::Value next = Next(); 4178bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch ReportUnexpectedToken(next); 4179bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch *ok = false; 4180bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch return NULL; 4181bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 4182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::COLON, CHECK_OK); 4185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* value = ParseAssignmentExpression(true, CHECK_OK); 4186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ObjectLiteral::Property* property = 41883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new(zone()) ObjectLiteral::Property(key, value, isolate()); 4189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 41903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Mark top-level object literals that contain function literals and 41913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // pretenure the literal so it can be added as a constant function 41923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // property. 41933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (top_scope_->DeclarationScope()->is_global_scope() && 41943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value->AsFunctionLiteral() != NULL) { 419544f0eee88ff00398ff7f715fab053374d808c90dSteve Block has_function = true; 41963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value->AsFunctionLiteral()->set_pretenure(); 419744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 419844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 4200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; 42011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Validate the property 42021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block checker.CheckProperty(property, loc, CHECK_OK); 42033e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu properties->Add(property); 4204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // TODO(1240767): Consider allowing trailing comma. 4206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 420780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 420880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (fni_ != NULL) { 420980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen fni_->Infer(); 421080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen fni_->Leave(); 421180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 4212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RBRACE, CHECK_OK); 42141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computation of literal_index must happen before pre parse bailout. 42163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int literal_index = current_function_state_->NextMaterializedLiteralIndex(); 4217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 421844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray( 421944f0eee88ff00398ff7f715fab053374d808c90dSteve Block number_of_boilerplate_properties * 2, TENURED); 42204515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 4221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_simple = true; 42226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool fast_elements = true; 4223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int depth = 1; 42243e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu BuildObjectLiteralConstantProperties(properties, 42254515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke constant_properties, 42264515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke &is_simple, 42276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block &fast_elements, 42284515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke &depth); 42293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewObjectLiteral(constant_properties, 42303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch properties, 42313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch literal_index, 42323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch is_simple, 42333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fast_elements, 42343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch depth, 42353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch has_function); 4236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { 4240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!scanner().ScanRegExpPattern(seen_equal)) { 4241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 4242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportMessage("unterminated_regexp", Vector<const char*>::empty()); 4243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *ok = false; 4244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 4245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int literal_index = current_function_state_->NextMaterializedLiteralIndex(); 4248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42499fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Handle<String> js_pattern = NextLiteralString(TENURED); 4250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch scanner().ScanRegExpFlags(); 42519fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Handle<String> js_flags = NextLiteralString(TENURED); 4252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 4253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index); 4255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockZoneList<Expression*>* Parser::ParseArguments(bool* ok) { 4259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Arguments :: 4260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '(' (AssignmentExpression)*[','] ')' 4261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4262257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4); 4263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LPAREN, CHECK_OK); 4264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done = (peek() == Token::RPAREN); 4265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!done) { 4266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expression* argument = ParseAssignmentExpression(true, CHECK_OK); 42673e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu result->Add(argument); 4268053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block if (result->length() > kMaxNumFunctionParameters) { 4269053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block ReportMessageAt(scanner().location(), "too_many_arguments", 4270053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block Vector<const char*>::empty()); 4271053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block *ok = false; 4272053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block return NULL; 4273053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block } 4274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block done = (peek() == Token::RPAREN); 4275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!done) Expect(Token::COMMA, CHECK_OK); 4276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 42783e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu return result; 4279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass SingletonLogger : public ParserRecorder { 42833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 42843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SingletonLogger() : has_error_(false), start_(-1), end_(-1) { } 42853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual ~SingletonLogger() { } 42863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Reset() { has_error_ = false; } 42883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void LogFunction(int start, 42903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int end, 42913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int literals, 42923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int properties, 42933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LanguageMode mode) { 42943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!has_error_); 42953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch start_ = start; 42963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch end_ = end; 42973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch literals_ = literals; 42983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch properties_ = properties; 42993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mode_ = mode; 43003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 43013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Logs a symbol creation of a literal or identifier. 43033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void LogAsciiSymbol(int start, Vector<const char> literal) { } 43043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { } 43053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Logs an error message and marks the log as containing an error. 43073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Further logging will be ignored, and ExtractData will return a vector 43083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // representing the error only. 43093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void LogMessage(int start, 43103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int end, 43113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* message, 43123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* argument_opt) { 43133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch has_error_ = true; 43143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch start_ = start; 43153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch end_ = end; 43163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch message_ = message; 43173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch argument_opt_ = argument_opt; 43183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual int function_position() { return 0; } 43213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual int symbol_position() { return 0; } 43233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual int symbol_ids() { return -1; } 43253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual Vector<unsigned> ExtractData() { 43273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 43283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Vector<unsigned>(); 43293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void PauseRecording() { } 43323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void ResumeRecording() { } 43343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool has_error() { return has_error_; } 43363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int start() { return start_; } 43383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int end() { return end_; } 43393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int literals() { 43403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!has_error_); 43413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return literals_; 43423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int properties() { 43443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!has_error_); 43453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return properties_; 43463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LanguageMode language_mode() { 43483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!has_error_); 43493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return mode_; 43503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* message() { 43523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(has_error_); 43533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return message_; 43543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* argument_opt() { 43563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(has_error_); 43573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return argument_opt_; 43583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 43613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool has_error_; 43623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int start_; 43633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int end_; 43643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // For function entries. 43653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int literals_; 43663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int properties_; 43673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LanguageMode mode_; 43683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // For error messages. 43693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* message_; 43703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* argument_opt_; 43713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 43723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43743fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochFunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, 43753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool name_is_strict_reserved, 4376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int function_token_position, 43773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch FunctionLiteral::Type type, 4378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* ok) { 4379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function :: 4380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '(' FormalParameterList? ')' '{' FunctionBody '}' 4381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Anonymous functions were passed either the empty symbol or a null 43833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // handle as the function name. Remember if we were passed a non-empty 43843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // handle to decide whether to invoke function name inference. 43853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool should_infer_name = function_name.is_null(); 43863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 43873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We want a non-null handle as the function name. 43883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (should_infer_name) { 43893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch function_name = isolate()->factory()->empty_symbol(); 4390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int num_parameters = 0; 439369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Function declarations are function scoped in normal mode, so they are 439469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // hoisted. In harmony block scoping mode they are block scoped, so they 439569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // are not hoisted. 43963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scope* scope = (type == FunctionLiteral::DECLARATION && !is_extended_mode()) 43973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) 43983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : NewScope(top_scope_, FUNCTION_SCOPE); 43993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ZoneList<Statement*>* body = NULL; 44003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int materialized_literal_count = -1; 44013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int expected_property_count = -1; 44023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int handler_count = 0; 44038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch bool only_simple_this_property_assignments; 44048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<FixedArray> this_property_assignments; 44053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionLiteral::ParameterFlag duplicate_parameters = 44063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionLiteral::kNoDuplicateParameters; 44073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AstProperties ast_properties; 4408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parse function body. 44093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { FunctionState function_state(this, scope, isolate()); 44103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch top_scope_->SetScopeName(function_name); 4411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // FormalParameterList :: 4413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '(' (Identifier)*[','] ')' 4414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LPAREN, CHECK_OK); 44153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->set_start_position(scanner().location().beg_pos); 4416257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Scanner::Location name_loc = Scanner::Location::invalid(); 4417257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Scanner::Location dupe_loc = Scanner::Location::invalid(); 4418257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Scanner::Location reserved_loc = Scanner::Location::invalid(); 44191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done = (peek() == Token::RPAREN); 4421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!done) { 44223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_strict_reserved = false; 44231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Handle<String> param_name = 44243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ParseIdentifierOrStrictReservedWord(&is_strict_reserved, 44253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_OK); 44261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 44271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Store locations for possible future error reports. 44281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { 44291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block name_loc = scanner().location(); 44301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 44311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { 44323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; 44331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block dupe_loc = scanner().location(); 44341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 44353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!reserved_loc.IsValid() && is_strict_reserved) { 44361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block reserved_loc = scanner().location(); 44371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 44381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 44393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_->DeclareParameter(param_name, VAR); 44403e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu num_parameters++; 44411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (num_parameters > kMaxNumFunctionParameters) { 44421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ReportMessageAt(scanner().location(), "too_many_parameters", 44431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Vector<const char*>::empty()); 44441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 44451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return NULL; 44461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block done = (peek() == Token::RPAREN); 4448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!done) Expect(Token::COMMA, CHECK_OK); 4449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::RPAREN, CHECK_OK); 4451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::LBRACE, CHECK_OK); 4453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we have a named function expression, we add a local variable 4455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // declaration to the body of the function with the name of the 4456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function and let it refer to the function itself (closure). 4457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // NOTE: We create a proxy and resolve it here so that in the 4458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // future we can change the AST to only refer to VariableProxies 4459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // instead of Variables and Proxis as is the case now. 44603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Variable* fvar = NULL; 44613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Token::Value fvar_init_op = Token::INIT_CONST; 44623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (type == FunctionLiteral::NAMED_EXPRESSION) { 44633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableMode fvar_mode; 44643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (is_extended_mode()) { 44653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fvar_mode = CONST_HARMONY; 44663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fvar_init_op = Token::INIT_CONST_HARMONY; 44673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 44683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fvar_mode = CONST; 44693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 44703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fvar = 44713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_->DeclareFunctionVar(function_name, fvar_mode, factory()); 44723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 44733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Determine whether the function will be lazily compiled. 44753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The heuristics are: 44763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // - It must not have been prohibited by the caller to Parse (some callers 44773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // need a full AST). 44783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // - The outer scope must be trivial (only global variables in scope). 44793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // - The function mustn't be a function expression with an open parenthesis 44803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // before; we consider that a hint that the function will be called 44813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // immediately, and it would be a waste of time to make it lazily 44823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // compiled. 44833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // These are all things we can know at this point, without looking at the 44843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // function itself. 4485b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool is_lazily_compiled = (mode() == PARSE_LAZILY && 4486b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch top_scope_->outer_scope()->is_global_scope() && 4487b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch top_scope_->HasTrivialOuterContext() && 44883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !parenthesized_function_); 4489b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch parenthesized_function_ = false; // The bit was set for this function only. 4490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_lazily_compiled) { 44923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int function_block_pos = scanner().location().beg_pos; 44933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionEntry entry; 44943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (pre_data_ != NULL) { 44953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If we have pre_data_, we use it to skip parsing the function body. 44963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the preparser data contains the information we need to construct the 44973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // lazy function. 44983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch entry = pre_data()->GetFunctionEntry(function_block_pos); 44993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry.is_valid()) { 45003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry.end_pos() <= function_block_pos) { 45013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // End position greater than end of stream is safe, and hard 45023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to check. 45033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReportInvalidPreparseData(function_name, CHECK_OK); 45043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scanner().SeekForward(entry.end_pos() - 1); 45063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->set_end_position(entry.end_pos()); 45083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expect(Token::RBRACE, CHECK_OK); 45093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->counters()->total_preparse_skipped()->Increment( 45103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->end_position() - function_block_pos); 45113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch materialized_literal_count = entry.literal_count(); 45123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expected_property_count = entry.property_count(); 45133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_->SetLanguageMode(entry.language_mode()); 45143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch only_simple_this_property_assignments = false; 45153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch this_property_assignments = isolate()->factory()->empty_fixed_array(); 45163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 45173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch is_lazily_compiled = false; 45183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 45203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // With no preparser data, we partially parse the function, without 45213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // building an AST. This gathers the data needed to build a lazy 45223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // function. 45233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SingletonLogger logger; 45243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch preparser::PreParser::PreParseResult result = 45253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LazyParseFunctionLiteral(&logger); 45263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (result == preparser::PreParser::kPreParseStackOverflow) { 45273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Propagate stack overflow. 45283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stack_overflow_ = true; 45293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *ok = false; 45303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return NULL; 4531592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 45323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (logger.has_error()) { 45333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* arg = logger.argument_opt(); 45343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Vector<const char*> args; 45353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (arg != NULL) { 45363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch args = Vector<const char*>(&arg, 1); 45373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReportMessageAt(Scanner::Location(logger.start(), logger.end()), 45393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch logger.message(), args); 45403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *ok = false; 45413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return NULL; 45423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->set_end_position(logger.end()); 45443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expect(Token::RBRACE, CHECK_OK); 45453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate()->counters()->total_preparse_skipped()->Increment( 45463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->end_position() - function_block_pos); 45473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch materialized_literal_count = logger.literals(); 45483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expected_property_count = logger.properties(); 45493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_->SetLanguageMode(logger.language_mode()); 45503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch only_simple_this_property_assignments = false; 45513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch this_property_assignments = isolate()->factory()->empty_fixed_array(); 4552ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke } 45533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 45543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 45553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!is_lazily_compiled) { 45563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch body = new(zone()) ZoneList<Statement*>(8); 45573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (fvar != NULL) { 45583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* fproxy = 45593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch top_scope_->NewUnresolved(factory(), function_name); 45603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fproxy->BindTo(fvar); 45613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch body->Add(factory()->NewExpressionStatement( 45623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewAssignment(fvar_init_op, 45633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fproxy, 45643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewThisFunction(), 45653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo::kNoPosition))); 45663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ParseSourceElements(body, Token::RBRACE, false, CHECK_OK); 45683e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 45693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch materialized_literal_count = function_state.materialized_literal_count(); 45703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expected_property_count = function_state.expected_property_count(); 45713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch handler_count = function_state.handler_count(); 4572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block only_simple_this_property_assignments = 45733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_state.only_simple_this_property_assignments(); 45743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch this_property_assignments = function_state.this_property_assignments(); 4575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 457680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Expect(Token::RBRACE, CHECK_OK); 45773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->set_end_position(scanner().location().end_pos); 4578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Validate strict mode. 45813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!top_scope_->is_classic_mode()) { 45823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (IsEvalOrArguments(function_name)) { 45833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int start_pos = scope->start_position(); 45841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int position = function_token_position != RelocInfo::kNoPosition 45851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ? function_token_position 45861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block : (start_pos > 0 ? start_pos - 1 : start_pos); 45871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Scanner::Location location = Scanner::Location(position, start_pos); 45881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ReportMessageAt(location, 45891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block "strict_function_name", Vector<const char*>::empty()); 45901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 45911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return NULL; 45921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 45931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (name_loc.IsValid()) { 45941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ReportMessageAt(name_loc, "strict_param_name", 45951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Vector<const char*>::empty()); 45961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 45971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return NULL; 45981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 45991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (dupe_loc.IsValid()) { 46001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ReportMessageAt(dupe_loc, "strict_param_dupe", 46011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Vector<const char*>::empty()); 46021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 46031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return NULL; 46041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 46053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (name_is_strict_reserved) { 46063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int start_pos = scope->start_position(); 46071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int position = function_token_position != RelocInfo::kNoPosition 46081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ? function_token_position 46091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block : (start_pos > 0 ? start_pos - 1 : start_pos); 46101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Scanner::Location location = Scanner::Location(position, start_pos); 46111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ReportMessageAt(location, "strict_reserved_word", 46121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Vector<const char*>::empty()); 46131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 46141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return NULL; 46151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 46161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (reserved_loc.IsValid()) { 46171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ReportMessageAt(reserved_loc, "strict_reserved_word", 46181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Vector<const char*>::empty()); 46191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 46201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return NULL; 46211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 46223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckOctalLiteral(scope->start_position(), 46233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope->end_position(), 46243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_OK); 46251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 46263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ast_properties = *factory()->visitor()->ast_properties(); 46278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 46281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 46293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (is_extended_mode()) { 4630589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch CheckConflictingVarDeclarations(scope, CHECK_OK); 4631589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 4632589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 46338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch FunctionLiteral* function_literal = 46343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewFunctionLiteral(function_name, 46353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope, 46363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch body, 46373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch materialized_literal_count, 46383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expected_property_count, 46393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch handler_count, 46403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch only_simple_this_property_assignments, 46413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch this_property_assignments, 46423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch num_parameters, 46433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch duplicate_parameters, 46443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch type, 46453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionLiteral::kIsFunction); 46468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch function_literal->set_function_token_position(function_token_position); 46473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_literal->set_ast_properties(&ast_properties); 46486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 46493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 46508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return function_literal; 4651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochpreparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral( 46553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SingletonLogger* logger) { 46563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); 46573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(Token::LBRACE, scanner().current_token()); 46583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (reusable_preparser_ == NULL) { 46603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t stack_limit = isolate()->stack_guard()->real_climit(); 46613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool do_allow_lazy = true; 46623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reusable_preparser_ = new preparser::PreParser(&scanner_, 46633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NULL, 46643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stack_limit, 46653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch do_allow_lazy, 46663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch allow_natives_syntax_, 46673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch allow_modules_); 46683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 46693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch preparser::PreParser::PreParseResult result = 46703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), 46713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch logger); 46723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return result; 46733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 46743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::ParseV8Intrinsic(bool* ok) { 4677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // CallRuntime :: 4678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // '%' Identifier Arguments 4679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::MOD, CHECK_OK); 4681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name = ParseIdentifier(CHECK_OK); 4682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 46830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 46840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (extension_ != NULL) { 4685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The extension structures are only accessible while parsing the 4686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // very first time not when reparsing because of lazy compilation. 46873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch top_scope_->DeclarationScope()->ForceEagerCompilation(); 4688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 469044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Runtime::Function* function = Runtime::FunctionForSymbol(name); 4691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Check for built-in IS_VAR macro. 46930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (function != NULL && 46940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen function->intrinsic_type == Runtime::RUNTIME && 46950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen function->function_id == Runtime::kIS_VAR) { 46960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // %IS_VAR(x) evaluates to x if x is a variable, 46970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // leads to a parse error otherwise. Could be implemented as an 46980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // inline function %_IS_VAR(x) to eliminate this special case. 46990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { 47000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return args->at(0); 47010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 4702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportMessage("unable_to_parse", Vector<const char*>::empty()); 47030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *ok = false; 4704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 4705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Check that the expected number of arguments are being passed. 47090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (function != NULL && 47100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen function->nargs != -1 && 47110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen function->nargs != args->length()) { 47120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ReportMessage("illegal_access", Vector<const char*>::empty()); 47130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *ok = false; 47140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return NULL; 47156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 47166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 47170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // We have a valid intrinsics call or a call to a builtin. 47183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewCallRuntime(name, function, args); 4719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockbool Parser::peek_any_identifier() { 47231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Token::Value next = peek(); 47241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return next == Token::IDENTIFIER || 47253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch next == Token::FUTURE_RESERVED_WORD || 47263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch next == Token::FUTURE_STRICT_RESERVED_WORD; 47271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 47281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 47291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Parser::Consume(Token::Value token) { 4731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value next = Next(); 4732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(next); 4733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(token); 4734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(next == token); 4735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Parser::Expect(Token::Value token, bool* ok) { 4739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value next = Next(); 4740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (next == token) return; 4741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportUnexpectedToken(next); 4742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *ok = false; 4743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47464515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkebool Parser::Check(Token::Value token) { 47474515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Token::Value next = peek(); 47484515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (next == token) { 47494515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Consume(next); 47504515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke return true; 47514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 47524515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke return false; 47534515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 47544515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 47554515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 4756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Parser::ExpectSemicolon(bool* ok) { 4757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check for automatic semicolon insertion according to 4758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the rules given in ECMA-262, section 7.9, page 21. 4759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value tok = peek(); 4760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (tok == Token::SEMICOLON) { 4761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 4762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 4763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 47643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (scanner().HasAnyLineTerminatorBeforeNext() || 4765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tok == Token::RBRACE || 4766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tok == Token::EOS) { 4767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 4768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expect(Token::SEMICOLON, ok); 4770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Parser::ExpectContextualKeyword(const char* keyword, bool* ok) { 47743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expect(Token::IDENTIFIER, ok); 47753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!*ok) return; 47763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> symbol = GetSymbol(ok); 47773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!*ok) return; 47783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!symbol->IsEqualTo(CStrVector(keyword))) { 47793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *ok = false; 47803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReportUnexpectedToken(scanner().current_token()); 47813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47853ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLiteral* Parser::GetLiteralUndefined() { 47863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewLiteral(isolate()->factory()->undefined_value()); 4787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47903ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLiteral* Parser::GetLiteralTheHole() { 47913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewLiteral(isolate()->factory()->the_hole_value()); 4792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 479569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Parses an identifier that is valid for the current scope, in particular it 47963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// fails on strict mode future reserved keywords in a strict scope. 4797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<String> Parser::ParseIdentifier(bool* ok) { 47983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!top_scope_->is_classic_mode()) { 47993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expect(Token::IDENTIFIER, ok); 48003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (!Check(Token::IDENTIFIER)) { 48013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); 48023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 48033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!*ok) return Handle<String>(); 48043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return GetSymbol(ok); 48051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 48061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 48071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 48083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Parses and identifier or a strict mode future reserved word, and indicate 48093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// whether it is strict mode future reserved. 48103fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<String> Parser::ParseIdentifierOrStrictReservedWord( 48113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool* is_strict_reserved, bool* ok) { 48123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch *is_strict_reserved = false; 48133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!Check(Token::IDENTIFIER)) { 48143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); 48153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch *is_strict_reserved = true; 48161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!*ok) return Handle<String>(); 48189ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick return GetSymbol(ok); 4819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4821bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4822bb769b257e753aafcbd96767abb2abc645eaa20cBen MurdochHandle<String> Parser::ParseIdentifierName(bool* ok) { 4823bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Token::Value next = Next(); 48241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (next != Token::IDENTIFIER && 48253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch next != Token::FUTURE_RESERVED_WORD && 48263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch next != Token::FUTURE_STRICT_RESERVED_WORD && 48273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch !Token::IsKeyword(next)) { 4828bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch ReportUnexpectedToken(next); 4829bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch *ok = false; 4830bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch return Handle<String>(); 4831bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 48329ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick return GetSymbol(ok); 4833bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4834bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4835bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 48363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Parser::MarkAsLValue(Expression* expression) { 48373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableProxy* proxy = expression != NULL 48383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? expression->AsVariableProxy() 48393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : NULL; 48403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (proxy != NULL) proxy->MarkAsLValue(); 48423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 48433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Checks LHS expression for assignment and prefix/postfix increment/decrement 48461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// in strict mode. 48471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid Parser::CheckStrictModeLValue(Expression* expression, 48481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block const char* error, 48491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool* ok) { 48503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!top_scope_->is_classic_mode()); 48511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block VariableProxy* lhs = expression != NULL 48521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ? expression->AsVariableProxy() 48531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block : NULL; 48541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 48551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { 48561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ReportMessage(error, Vector<const char*>::empty()); 48571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 48581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 48591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 48601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 48611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4862257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Checks whether an octal literal was last seen between beg_pos and end_pos. 4863257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// If so, reports an error. Only called for strict mode. 48641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { 4865257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Scanner::Location octal = scanner().octal_position(); 4866257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (octal.IsValid() && 4867257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch beg_pos <= octal.beg_pos && 4868257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch octal.end_pos <= end_pos) { 4869257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ReportMessageAt(octal, "strict_octal_literal", 48701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Vector<const char*>::empty()); 48711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block scanner().clear_octal_position(); 48721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block *ok = false; 48731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 48741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 48751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 48761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4877589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { 4878589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Declaration* decl = scope->CheckConflictingVarDeclarations(); 4879589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (decl != NULL) { 4880589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // In harmony mode we treat conflicting variable bindinds as early 4881589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // errors. See ES5 16 for a definition of early errors. 4882589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Handle<String> name = decl->proxy()->name(); 4883589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); 4884589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch const char* elms[2] = { "Variable", *c_string }; 4885589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Vector<const char*> args(elms, 2); 4886589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch int position = decl->proxy()->position(); 4887589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Scanner::Location location = position == RelocInfo::kNoPosition 4888589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ? Scanner::Location::invalid() 4889589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch : Scanner::Location(position, position + 1); 4890589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ReportMessageAt(location, "redeclaration", args); 4891589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch *ok = false; 4892589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 4893589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 4894589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 4895589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 48963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// This function reads an identifier name and determines whether or not it 48971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// is 'get' or 'set'. 48983fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, 48993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool* is_set, 49003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool* ok) { 49013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> result = ParseIdentifierName(ok); 4902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!*ok) return Handle<String>(); 49039fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { 49049fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block const char* token = scanner().literal_ascii_string().start(); 49059fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block *is_get = strncmp(token, "get", 3) == 0; 49069fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block *is_set = !*is_get && strncmp(token, "set", 3) == 0; 4907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 49081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return result; 4909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 4913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Parser support 4914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Parser::TargetStackContainsLabel(Handle<String> label) { 4917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (Target* t = target_stack_; t != NULL; t = t->previous()) { 4918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakableStatement* stat = t->node()->AsBreakableStatement(); 4919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (stat != NULL && ContainsLabel(stat->labels(), label)) 4920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 4921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 4923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { 4927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool anonymous = label.is_null(); 4928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (Target* t = target_stack_; t != NULL; t = t->previous()) { 4929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakableStatement* stat = t->node()->AsBreakableStatement(); 4930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (stat == NULL) continue; 4931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((anonymous && stat->is_target_for_anonymous()) || 4932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (!anonymous && ContainsLabel(stat->labels(), label))) { 4933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegisterTargetUse(stat->break_target(), t->previous()); 4934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return stat; 4935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 4938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockIterationStatement* Parser::LookupContinueTarget(Handle<String> label, 4942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* ok) { 4943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool anonymous = label.is_null(); 4944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (Target* t = target_stack_; t != NULL; t = t->previous()) { 4945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IterationStatement* stat = t->node()->AsIterationStatement(); 4946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (stat == NULL) continue; 4947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(stat->is_target_for_anonymous()); 4949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (anonymous || ContainsLabel(stat->labels(), label)) { 4950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegisterTargetUse(stat->continue_target(), t->previous()); 4951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return stat; 4952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 4955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid Parser::RegisterTargetUse(Label* target, Target* stop) { 4959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register that a break target found at the given stop in the 4960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // target stack has been used from the top of the target stack. Add 4961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the break target to any TargetCollectors passed on the stack. 4962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (Target* t = target_stack_; t != stop; t = t->previous()) { 4963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TargetCollector* collector = t->node()->AsTargetCollector(); 4964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (collector != NULL) collector->AddTarget(target); 4965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::NewThrowReferenceError(Handle<String> type) { 497044f0eee88ff00398ff7f715fab053374d808c90dSteve Block return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(), 4971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block type, HandleVector<Object>(NULL, 0)); 4972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::NewThrowSyntaxError(Handle<String> type, 4976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> first) { 4977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc = first.is_null() ? 0 : 1; 4978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc); 497944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return NewThrowError( 498044f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()->MakeSyntaxError_symbol(), type, arguments); 4981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::NewThrowTypeError(Handle<String> type, 4985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> first, 4986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> second) { 4987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!first.is_null() && !second.is_null()); 4988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> elements[] = { first, second }; 4989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector< Handle<Object> > arguments = 4990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleVector<Object>(elements, ARRAY_SIZE(elements)); 499144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return NewThrowError( 499244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()->MakeTypeError_symbol(), type, arguments); 4993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExpression* Parser::NewThrowError(Handle<String> constructor, 4997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> type, 4998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector< Handle<Object> > arguments) { 4999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc = arguments.length(); 500044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc, 500144f0eee88ff00398ff7f715fab053374d808c90dSteve Block TENURED); 5002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < argc; i++) { 5003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> element = arguments[i]; 5004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!element.is_null()) { 50051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block elements->set(i, *element); 5006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 50083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements( 50093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elements, FAST_ELEMENTS, TENURED); 50101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5011257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2); 50123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch args->Add(factory()->NewLiteral(type)); 50133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch args->Add(factory()->NewLiteral(array)); 50143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime* call_constructor = 50153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewCallRuntime(constructor, NULL, args); 50163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return factory()->NewThrow(call_constructor, scanner().location().beg_pos); 5017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke// ---------------------------------------------------------------------------- 5020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Regular expressions 5021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpParser::RegExpParser(FlatStringReader* in, 5024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String>* error, 5025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool multiline) 502644f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(Isolate::Current()), 502744f0eee88ff00398ff7f715fab053374d808c90dSteve Block error_(error), 502844f0eee88ff00398ff7f715fab053374d808c90dSteve Block captures_(NULL), 502944f0eee88ff00398ff7f715fab053374d808c90dSteve Block in_(in), 503044f0eee88ff00398ff7f715fab053374d808c90dSteve Block current_(kEndMarker), 503144f0eee88ff00398ff7f715fab053374d808c90dSteve Block next_pos_(0), 503244f0eee88ff00398ff7f715fab053374d808c90dSteve Block capture_count_(0), 503344f0eee88ff00398ff7f715fab053374d808c90dSteve Block has_more_(true), 503444f0eee88ff00398ff7f715fab053374d808c90dSteve Block multiline_(multiline), 503544f0eee88ff00398ff7f715fab053374d808c90dSteve Block simple_(false), 503644f0eee88ff00398ff7f715fab053374d808c90dSteve Block contains_anchor_(false), 503744f0eee88ff00398ff7f715fab053374d808c90dSteve Block is_scanned_for_captures_(false), 503844f0eee88ff00398ff7f715fab053374d808c90dSteve Block failed_(false) { 5039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Advance(); 5040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuc32 RegExpParser::Next() { 5044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (has_next()) { 5045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return in()->Get(next_pos_); 5046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return kEndMarker; 5048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpParser::Advance() { 5053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (next_pos_ < in()->length()) { 505444f0eee88ff00398ff7f715fab053374d808c90dSteve Block StackLimitCheck check(isolate()); 5055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (check.HasOverflowed()) { 505644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ReportError(CStrVector(Isolate::kStackOverflowMessage)); 505744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (isolate()->zone()->excess_allocation()) { 5058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportError(CStrVector("Regular expression too large")); 5059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_ = in()->Get(next_pos_); 5061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next_pos_++; 5062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_ = kEndMarker; 5065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block has_more_ = false; 5066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpParser::Reset(int pos) { 5071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next_pos_ = pos; 5072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpParser::Advance(int dist) { 5077b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch next_pos_ += dist - 1; 5078b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Advance(); 5079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool RegExpParser::simple() { 5083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return simple_; 5084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpTree* RegExpParser::ReportError(Vector<const char> message) { 5087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block failed_ = true; 508844f0eee88ff00398ff7f715fab053374d808c90dSteve Block *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED); 5089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Zip to the end to make sure the no more input is read. 5090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_ = kEndMarker; 5091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next_pos_ = in()->length(); 5092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 5093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Pattern :: 5097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Disjunction 5098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpTree* RegExpParser::ParsePattern() { 5099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpTree* result = ParseDisjunction(CHECK_FAILED); 5100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!has_more()); 5101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the result of parsing is a literal string atom, and it has the 5102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // same length as the input, then the atom is identical to the input. 5103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsAtom() && result->AsAtom()->length() == in()->length()) { 5104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block simple_ = true; 5105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 5107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Disjunction :: 5111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Alternative 5112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Alternative | Disjunction 5113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Alternative :: 5114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// [empty] 5115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Term Alternative 5116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Term :: 5117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Assertion 5118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Atom 5119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Atom Quantifier 5120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpTree* RegExpParser::ParseDisjunction() { 5121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Used to store current state while parsing subexpressions. 5122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpParserState initial_state(NULL, INITIAL, 0); 5123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpParserState* stored_state = &initial_state; 5124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Cache the builder in a local variable for quick access. 5125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpBuilder* builder = initial_state.builder(); 5126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 5127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (current()) { 5128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case kEndMarker: 5129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (stored_state->IsSubexpression()) { 5130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Inside a parenthesized group when hitting end of input. 5131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportError(CStrVector("Unterminated group") CHECK_FAILED); 5132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_EQ(INITIAL, stored_state->group_type()); 5134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parsing completed successfully. 5135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return builder->ToRegExp(); 5136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case ')': { 5137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!stored_state->IsSubexpression()) { 5138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportError(CStrVector("Unmatched ')'") CHECK_FAILED); 5139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_NE(INITIAL, stored_state->group_type()); 5141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // End disjunction parsing and convert builder content to new single 5144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // regexp atom. 5145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpTree* body = builder->ToRegExp(); 5146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int end_capture_index = captures_started(); 5148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int capture_index = stored_state->capture_index(); 5150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SubexpressionType type = stored_state->group_type(); 5151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Restore previous state. 5153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stored_state = stored_state->previous_state(); 5154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder = stored_state->builder(); 5155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Build result of subexpression. 5157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (type == CAPTURE) { 51588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index); 5159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block captures_->at(capture_index - 1) = capture; 5160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block body = capture; 5161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (type != GROUPING) { 5162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD); 5163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_positive = (type == POSITIVE_LOOKAHEAD); 51648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch body = new(zone()) RegExpLookahead(body, 5165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_positive, 5166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block end_capture_index - capture_index, 5167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block capture_index); 5168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddAtom(body); 5170e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // For compatability with JSC and ES3, we allow quantifiers after 5171e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // lookaheads, and break in all cases. 5172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '|': { 5175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->NewAlternative(); 5177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 5178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '*': 5180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '+': 5181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '?': 5182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ReportError(CStrVector("Nothing to repeat")); 5183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '^': { 5184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (multiline_) { 5186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddAssertion( 51878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE)); 5188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddAssertion( 51908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT)); 5191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_contains_anchor(); 5192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 5194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '$': { 5196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpAssertion::Type type = 5198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block multiline_ ? RegExpAssertion::END_OF_LINE : 5199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpAssertion::END_OF_INPUT; 52008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch builder->AddAssertion(new(zone()) RegExpAssertion(type)); 5201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 5202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '.': { 5204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // everything except \x0a, \x0d, \u2028 and \u2029 5206257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneList<CharacterRange>* ranges = 5207257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch new(zone()) ZoneList<CharacterRange>(2); 5208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange::AddClassEscape('.', ranges); 52098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); 5210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddAtom(atom); 5211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '(': { 5214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SubexpressionType type = CAPTURE; 5215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current() == '?') { 5217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (Next()) { 5218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case ':': 5219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block type = GROUPING; 5220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '=': 5222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block type = POSITIVE_LOOKAHEAD; 5223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '!': 5225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block type = NEGATIVE_LOOKAHEAD; 5226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 5228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportError(CStrVector("Invalid group") CHECK_FAILED); 5229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (captures_ == NULL) { 5234257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch captures_ = new(zone()) ZoneList<RegExpCapture*>(2); 5235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (captures_started() >= kMaxCaptures) { 5237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportError(CStrVector("Too many captures") CHECK_FAILED); 5238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block captures_->Add(NULL); 5240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Store current state and begin new disjunction parsing. 52428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch stored_state = new(zone()) RegExpParserState(stored_state, 5243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block type, 5244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block captures_started()); 5245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder = stored_state->builder(); 5246e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; 5247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '[': { 5249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpTree* atom = ParseCharacterClass(CHECK_FAILED); 5250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddAtom(atom); 5251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Atom :: 5254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // \ AtomEscape 5255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '\\': 5256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (Next()) { 5257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case kEndMarker: 5258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ReportError(CStrVector("\\ at end of pattern")); 5259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'b': 5260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddAssertion( 52628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY)); 5263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 5264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'B': 5265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddAssertion( 52678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY)); 5268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 5269e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // AtomEscape :: 5270e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // CharacterClassEscape 5271e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // 5272e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // CharacterClassEscape :: one of 5273e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // d D s S w W 5274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'd': case 'D': case 's': case 'S': case 'w': case 'W': { 5275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 c = Next(); 5276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5277257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneList<CharacterRange>* ranges = 5278257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch new(zone()) ZoneList<CharacterRange>(2); 5279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange::AddClassEscape(c, ranges); 52808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); 5281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddAtom(atom); 5282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '1': case '2': case '3': case '4': case '5': case '6': 5285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '7': case '8': case '9': { 5286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index = 0; 5287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ParseBackReferenceIndex(&index)) { 5288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpCapture* capture = NULL; 5289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (captures_ != NULL && index <= captures_->length()) { 5290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block capture = captures_->at(index - 1); 5291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (capture == NULL) { 5293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddEmpty(); 5294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 52968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RegExpTree* atom = new(zone()) RegExpBackReference(capture); 5297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddAtom(atom); 5298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 first_digit = Next(); 5301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (first_digit == '8' || first_digit == '9') { 5302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Treat as identity escape 5303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter(first_digit); 5304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // FALLTHROUGH 5309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '0': { 5310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 octal = ParseOctalLiteral(); 5312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter(octal); 5313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ControlEscape :: one of 5316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // f n r t v 5317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'f': 5318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter('\f'); 5320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'n': 5322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter('\n'); 5324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'r': 5326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter('\r'); 5328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 't': 5330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter('\t'); 5332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'v': 5334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter('\v'); 5336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'c': { 5338086aeeaae12517475c22695a200be45495516549Ben Murdoch Advance(); 5339086aeeaae12517475c22695a200be45495516549Ben Murdoch uc32 controlLetter = Next(); 5340086aeeaae12517475c22695a200be45495516549Ben Murdoch // Special case if it is an ASCII letter. 5341086aeeaae12517475c22695a200be45495516549Ben Murdoch // Convert lower case letters to uppercase. 5342086aeeaae12517475c22695a200be45495516549Ben Murdoch uc32 letter = controlLetter & ~('a' ^ 'A'); 5343086aeeaae12517475c22695a200be45495516549Ben Murdoch if (letter < 'A' || 'Z' < letter) { 5344086aeeaae12517475c22695a200be45495516549Ben Murdoch // controlLetter is not in range 'A'-'Z' or 'a'-'z'. 5345086aeeaae12517475c22695a200be45495516549Ben Murdoch // This is outside the specification. We match JSC in 5346086aeeaae12517475c22695a200be45495516549Ben Murdoch // reading the backslash as a literal character instead 5347086aeeaae12517475c22695a200be45495516549Ben Murdoch // of as starting an escape. 5348086aeeaae12517475c22695a200be45495516549Ben Murdoch builder->AddCharacter('\\'); 5349086aeeaae12517475c22695a200be45495516549Ben Murdoch } else { 5350086aeeaae12517475c22695a200be45495516549Ben Murdoch Advance(2); 5351086aeeaae12517475c22695a200be45495516549Ben Murdoch builder->AddCharacter(controlLetter & 0x1f); 5352086aeeaae12517475c22695a200be45495516549Ben Murdoch } 5353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'x': { 5356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 value; 5358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ParseHexEscape(2, &value)) { 5359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter(value); 5360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter('x'); 5362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'u': { 5366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 value; 5368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ParseHexEscape(4, &value)) { 5369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter(value); 5370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter('u'); 5372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 5376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Identity escape. 5377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter(Next()); 5378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '{': { 5383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int dummy; 5384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ParseIntervalQuantifier(&dummy, &dummy)) { 5385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportError(CStrVector("Nothing to repeat") CHECK_FAILED); 5386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // fallthrough 5388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 5390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder->AddCharacter(current()); 5391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } // end switch(current()) 5394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int min; 5396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int max; 5397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (current()) { 5398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // QuantifierPrefix :: 5399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // * 5400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // + 5401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ? 5402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // { 5403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '*': 5404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block min = 0; 5405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max = RegExpTree::kInfinity; 5406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '+': 5409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block min = 1; 5410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max = RegExpTree::kInfinity; 5411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '?': 5414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block min = 0; 5415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max = 1; 5416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '{': 5419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ParseIntervalQuantifier(&min, &max)) { 5420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (max < min) { 5421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportError(CStrVector("numbers out of order in {} quantifier.") 5422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_FAILED); 5423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 5427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 5429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 5430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5431e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke RegExpQuantifier::Type type = RegExpQuantifier::GREEDY; 5432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current() == '?') { 5433e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke type = RegExpQuantifier::NON_GREEDY; 5434e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Advance(); 5435e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else if (FLAG_regexp_possessive_quantifier && current() == '+') { 5436e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // FLAG_regexp_possessive_quantifier is a debug-only flag. 5437e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke type = RegExpQuantifier::POSSESSIVE; 5438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5440e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke builder->AddQuantifierToAtom(min, max, type); 5441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 5446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Currently only used in an ASSERT. 5447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool IsSpecialClassEscape(uc32 c) { 5448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (c) { 5449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'd': case 'D': 5450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 's': case 'S': 5451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'w': case 'W': 5452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 5453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 5454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 5455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 5458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// In order to know whether an escape is a backreference or not we have to scan 5461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the entire regexp and find the number of capturing parentheses. However we 5462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// don't want to scan the regexp twice unless it is necessary. This mini-parser 5463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// is called when needed. It can see the difference between capturing and 5464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// noncapturing parentheses and can skip character classes and backslash-escaped 5465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// characters. 5466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpParser::ScanForCaptures() { 5467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Start with captures started previous to current position 5468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int capture_count = captures_started(); 5469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Add count of captures after this position. 5470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int n; 5471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while ((n = current()) != kEndMarker) { 5472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (n) { 5474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '\\': 5475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '[': { 5478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int c; 5479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while ((c = current()) != kEndMarker) { 5480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c == '\\') { 5482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c == ']') break; 5485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '(': 5490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current() != '?') capture_count++; 5491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block capture_count_ = capture_count; 5495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_scanned_for_captures_ = true; 5496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool RegExpParser::ParseBackReferenceIndex(int* index_out) { 5500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_EQ('\\', current()); 5501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT('1' <= Next() && Next() <= '9'); 5502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Try to parse a decimal literal that is no greater than the total number 5503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // of left capturing parentheses in the input. 5504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int start = position(); 5505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int value = Next() - '0'; 5506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 5508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 c = current(); 5509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDecimalDigit(c)) { 5510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value = 10 * value + (c - '0'); 5511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value > kMaxCaptures) { 5512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(start); 5513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 5514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value > captures_started()) { 5521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!is_scanned_for_captures_) { 5522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int saved_position = position(); 5523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScanForCaptures(); 5524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(saved_position); 5525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value > capture_count_) { 5527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(start); 5528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 5529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *index_out = value; 5532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 5533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// QuantifierPrefix :: 5537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// { DecimalDigits } 5538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// { DecimalDigits , } 5539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// { DecimalDigits , DecimalDigits } 5540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 5541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns true if parsing succeeds, and set the min_out and max_out 5542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// values. Values are truncated to RegExpTree::kInfinity if they overflow. 5543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) { 5544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_EQ(current(), '{'); 5545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int start = position(); 5546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int min = 0; 5548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsDecimalDigit(current())) { 5549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(start); 5550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 5551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (IsDecimalDigit(current())) { 5553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int next = current() - '0'; 5554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (min > (RegExpTree::kInfinity - next) / 10) { 5555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Overflow. Skip past remaining decimal digits and return -1. 5556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { 5557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (IsDecimalDigit(current())); 5559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block min = RegExpTree::kInfinity; 5560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block min = 10 * min + next; 5563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int max = 0; 5566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current() == '}') { 5567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max = min; 5568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (current() == ',') { 5570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current() == '}') { 5572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max = RegExpTree::kInfinity; 5573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (IsDecimalDigit(current())) { 5576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int next = current() - '0'; 5577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (max > (RegExpTree::kInfinity - next) / 10) { 5578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { 5579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (IsDecimalDigit(current())); 5581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max = RegExpTree::kInfinity; 5582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max = 10 * max + next; 5585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current() != '}') { 5588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(start); 5589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 5590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(start); 5595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 5596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *min_out = min; 5598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *max_out = max; 5599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 5600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuc32 RegExpParser::ParseOctalLiteral() { 5604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT('0' <= current() && current() <= '7'); 5605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For compatibility with some other browsers (not all), we parse 5606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // up to three octal digits with a value below 256. 5607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 value = current() - '0'; 5608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ('0' <= current() && current() <= '7') { 5610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value = value * 8 + current() - '0'; 5611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value < 32 && '0' <= current() && current() <= '7') { 5613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value = value * 8 + current() - '0'; 5614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return value; 5618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool RegExpParser::ParseHexEscape(int length, uc32 *value) { 5622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int start = position(); 5623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 val = 0; 5624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done = false; 5625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; !done; i++) { 5626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 c = current(); 5627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int d = HexValue(c); 5628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (d < 0) { 5629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(start); 5630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 5631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block val = val * 16 + d; 5633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i == length - 1) { 5635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block done = true; 5636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *value = val; 5639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 5640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuc32 RegExpParser::ParseClassCharacterEscape() { 5644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(current() == '\\'); 5645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(has_next() && !IsSpecialClassEscape(Next())); 5646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (current()) { 5648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'b': 5649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return '\b'; 5651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ControlEscape :: one of 5652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // f n r t v 5653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'f': 5654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return '\f'; 5656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'n': 5657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return '\n'; 5659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'r': 5660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return '\r'; 5662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 't': 5663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return '\t'; 5665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'v': 5666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return '\v'; 5668086aeeaae12517475c22695a200be45495516549Ben Murdoch case 'c': { 5669086aeeaae12517475c22695a200be45495516549Ben Murdoch uc32 controlLetter = Next(); 5670086aeeaae12517475c22695a200be45495516549Ben Murdoch uc32 letter = controlLetter & ~('A' ^ 'a'); 5671086aeeaae12517475c22695a200be45495516549Ben Murdoch // For compatibility with JSC, inside a character class 5672086aeeaae12517475c22695a200be45495516549Ben Murdoch // we also accept digits and underscore as control characters. 5673086aeeaae12517475c22695a200be45495516549Ben Murdoch if ((controlLetter >= '0' && controlLetter <= '9') || 5674086aeeaae12517475c22695a200be45495516549Ben Murdoch controlLetter == '_' || 5675086aeeaae12517475c22695a200be45495516549Ben Murdoch (letter >= 'A' && letter <= 'Z')) { 5676086aeeaae12517475c22695a200be45495516549Ben Murdoch Advance(2); 5677086aeeaae12517475c22695a200be45495516549Ben Murdoch // Control letters mapped to ASCII control characters in the range 5678086aeeaae12517475c22695a200be45495516549Ben Murdoch // 0x00-0x1f. 5679086aeeaae12517475c22695a200be45495516549Ben Murdoch return controlLetter & 0x1f; 5680086aeeaae12517475c22695a200be45495516549Ben Murdoch } 5681086aeeaae12517475c22695a200be45495516549Ben Murdoch // We match JSC in reading the backslash as a literal 5682086aeeaae12517475c22695a200be45495516549Ben Murdoch // character instead of as starting an escape. 5683086aeeaae12517475c22695a200be45495516549Ben Murdoch return '\\'; 5684086aeeaae12517475c22695a200be45495516549Ben Murdoch } 5685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '0': case '1': case '2': case '3': case '4': case '5': 5686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '6': case '7': 5687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For compatibility, we interpret a decimal escape that isn't 5688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a back reference (and therefore either \0 or not valid according 5689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to the specification) as a 1..3 digit octal character code. 5690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ParseOctalLiteral(); 5691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'x': { 5692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 value; 5694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ParseHexEscape(2, &value)) { 5695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return value; 5696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If \x is not followed by a two-digit hexadecimal, treat it 5698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // as an identity escape. 5699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 'x'; 5700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'u': { 5702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 value; 5704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ParseHexEscape(4, &value)) { 5705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return value; 5706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If \u is not followed by a four-digit hexadecimal, treat it 5708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // as an identity escape. 5709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 'u'; 5710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: { 5712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Extended identity escape. We accept any character that hasn't 5713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // been matched by a more specific case, not just the subset required 5714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by the ECMAScript specification. 5715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 result = current(); 5716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 5718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0; 5721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCharacterRange RegExpParser::ParseClassAtom(uc16* char_class) { 5725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_EQ(0, *char_class); 5726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 first = current(); 5727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (first == '\\') { 5728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (Next()) { 5729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'w': case 'W': case 'd': case 'D': case 's': case 'S': { 5730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *char_class = Next(); 5731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(2); 5732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return CharacterRange::Singleton(0); // Return dummy value. 5733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case kEndMarker: 5735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ReportError(CStrVector("\\ at end of pattern")); 5736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 5737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 c = ParseClassCharacterEscape(CHECK_FAILED); 5738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return CharacterRange::Singleton(c); 5739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return CharacterRange::Singleton(first); 5743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5747b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic const uc16 kNoCharClass = 0; 5748b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5749b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Adds range or pre-defined character class to character ranges. 5750b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// If char_class is not kInvalidClass, it's interpreted as a class 5751b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// escape (i.e., 's' means whitespace, from '\s'). 5752b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges, 5753b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch uc16 char_class, 5754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CharacterRange range) { 5755b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (char_class != kNoCharClass) { 5756b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CharacterRange::AddClassEscape(char_class, ranges); 5757b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 5758b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ranges->Add(range); 5759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 5760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 5761b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5762b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpTree* RegExpParser::ParseCharacterClass() { 5764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const char* kUnterminated = "Unterminated character class"; 5765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const char* kRangeOutOfOrder = "Range out of order in character class"; 5766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_EQ(current(), '['); 5768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_negated = false; 5770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current() == '^') { 5771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_negated = true; 5772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5774257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneList<CharacterRange>* ranges = new(zone()) ZoneList<CharacterRange>(2); 5775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (has_more() && current() != ']') { 5776b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch uc16 char_class = kNoCharClass; 5777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED); 5778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current() == '-') { 5779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current() == kEndMarker) { 5781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we reach the end we break out of the loop and let the 5782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // following code report an error. 5783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (current() == ']') { 5785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AddRangeOrEscape(ranges, char_class, first); 5786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ranges->Add(CharacterRange::Singleton('-')); 5787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 5788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch uc16 char_class_2 = kNoCharClass; 5790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED); 5791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (char_class != kNoCharClass || char_class_2 != kNoCharClass) { 5792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Either end is an escaped character class. Treat the '-' verbatim. 5793b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AddRangeOrEscape(ranges, char_class, first); 5794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ranges->Add(CharacterRange::Singleton('-')); 5795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AddRangeOrEscape(ranges, char_class_2, next); 5796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 5797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (first.from() > next.to()) { 5799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED); 5800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ranges->Add(CharacterRange::Range(first.from(), next.to())); 5802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AddRangeOrEscape(ranges, char_class, first); 5804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!has_more()) { 5807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ReportError(CStrVector(kUnterminated) CHECK_FAILED); 5808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 5810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ranges->length() == 0) { 5811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ranges->Add(CharacterRange::Everything()); 5812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_negated = !is_negated; 5813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 58148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return new(zone()) RegExpCharacterClass(ranges, is_negated); 5815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 5819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The Parser interface. 5820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockParserMessage::~ParserMessage() { 5822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < args().length(); i++) 5823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(args()[i]); 5824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(args().start()); 5825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockScriptDataImpl::~ScriptDataImpl() { 58299ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick if (owns_store_) store_.Dispose(); 5830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint ScriptDataImpl::Length() { 5834f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke return store_.length() * sizeof(unsigned); 5835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5838f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeconst char* ScriptDataImpl::Data() { 5839f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke return reinterpret_cast<const char*>(store_.start()); 5840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5843e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkebool ScriptDataImpl::HasError() { 5844e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return has_error(); 5845e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 5846e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5847e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 58480d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid ScriptDataImpl::Initialize() { 58490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Prepares state for use. 58508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (store_.length() >= PreparseDataConstants::kHeaderSize) { 58518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang function_index_ = PreparseDataConstants::kHeaderSize; 58528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int symbol_data_offset = PreparseDataConstants::kHeaderSize 58538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang + store_[PreparseDataConstants::kFunctionsSizeOffset]; 58540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (store_.length() > symbol_data_offset) { 58550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); 58560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 58570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Partial preparse causes no symbol information. 58580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 58590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 58600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 58610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 58620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 58630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 58640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 58650d5e116f6aee03185f237311a943491bb079a768Kristian Monsenint ScriptDataImpl::ReadNumber(byte** source) { 58660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Reads a number from symbol_data_ in base 128. The most significant 58670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // bit marks that there are more digits. 58680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // If the first byte is 0x80 (kNumberTerminator), it would normally 58690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // represent a leading zero. Since that is useless, and therefore won't 58700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // appear as the first digit of any actual value, it is used to 58710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // mark the end of the input stream. 58720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen byte* data = *source; 58730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (data >= symbol_data_end_) return -1; 58740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen byte input = *data; 58758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (input == PreparseDataConstants::kNumberTerminator) { 58760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // End of stream marker. 58770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return -1; 58780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 58790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int result = input & 0x7f; 58800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen data++; 58810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen while ((input & 0x80u) != 0) { 58820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (data >= symbol_data_end_) return -1; 58830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen input = *data; 58840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen result = (result << 7) | (input & 0x7f); 58850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen data++; 58860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 58870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *source = data; 58880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return result; 58890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 58900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 58910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 58928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// Create a Scanner for the preparser to use as input, and preparse the source. 58933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic ScriptDataImpl* DoPreParse(Utf16CharacterStream* source, 58943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int flags, 58953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ParserRecorder* recorder) { 589644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 58973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HistogramTimerScope timer(isolate->counters()->pre_parse()); 58983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Scanner scanner(isolate->unicode_cache()); 58993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scanner.SetHarmonyScoping(FLAG_harmony_scoping); 59009fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block scanner.Initialize(source); 590144f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t stack_limit = isolate->stack_guard()->real_climit(); 59023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch preparser::PreParser::PreParseResult result = 59033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch preparser::PreParser::PreParseProgram(&scanner, 59043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch recorder, 59053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags, 59063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stack_limit); 59073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (result == preparser::PreParser::kPreParseStackOverflow) { 590844f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->StackOverflow(); 59098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return NULL; 59108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 59118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 59128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // Extract the accumulated data from the recorder as a single 59138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // contiguous vector that we are responsible for disposing. 59148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Vector<unsigned> store = recorder->ExtractData(); 59158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return new ScriptDataImpl(store); 59168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 59178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 59188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 59193e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu// Preparse, but only collect data that is immediately useful, 59203e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu// even if the preparser data is only used once. 59213ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source, 592269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Extension* extension, 59233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int flags) { 59243e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu bool allow_lazy = FLAG_lazy && (extension == NULL); 59253e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (!allow_lazy) { 59263e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Partial preparsing is only about lazily compiled functions. 59273e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // If we don't allow lazy compilation, the log data will be empty. 59283e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu return NULL; 59293e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu } 59303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags |= kAllowLazy; 59313e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu PartialParserRecorder recorder; 59323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int source_length = source->length(); 59333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (source->IsExternalTwoByteString()) { 59343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalTwoByteStringUtf16CharacterStream stream( 59353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<ExternalTwoByteString>::cast(source), 0, source_length); 59363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return DoPreParse(&stream, flags, &recorder); 59373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 59383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GenericStringUtf16CharacterStream stream(source, 0, source_length); 59393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return DoPreParse(&stream, flags, &recorder); 59403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 59413e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu} 59423e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 59433e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 59443ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochScriptDataImpl* ParserApi::PreParse(Utf16CharacterStream* source, 594569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Extension* extension, 59463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int flags) { 5947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Script> no_script; 59483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_lazy && (extension == NULL)) { 59493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags |= kAllowLazy; 59503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 59513e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu CompleteParserRecorder recorder; 59523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return DoPreParse(source, flags, &recorder); 5953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 59563e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhubool RegExpParser::ParseRegExp(FlatStringReader* input, 59573e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu bool multiline, 59583e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu RegExpCompileData* result) { 5959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(result != NULL); 5960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpParser parser(input, &result->error, multiline); 5961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpTree* tree = parser.ParsePattern(); 5962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (parser.failed()) { 5963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(tree == NULL); 5964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!result->error.is_null()); 5965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(tree != NULL); 5967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(result->error.is_null()); 5968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->tree = tree; 5969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int capture_count = parser.captures_started(); 5970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; 5971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->contains_anchor = parser.contains_anchor(); 5972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->capture_count = capture_count; 5973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return !parser.failed(); 5975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 59783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool ParserApi::Parse(CompilationInfo* info, int parsing_flags) { 5979f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(info->function() == NULL); 5980f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch FunctionLiteral* result = NULL; 5981f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Script> script = info->script(); 59823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((parsing_flags & kLanguageModeMask) == CLASSIC_MODE); 59833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!info->is_native() && FLAG_harmony_scoping) { 59843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Harmony scoping is requested. 59853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parsing_flags |= EXTENDED_MODE; 59863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 59873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!info->is_native() && FLAG_harmony_modules) { 59883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parsing_flags |= kAllowModules; 59893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 59903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_allow_natives_syntax || info->is_native()) { 59913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We require %identifier(..) syntax. 59923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parsing_flags |= kAllowNativesSyntax; 59933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5994f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (info->is_lazy()) { 59953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!info->is_eval()); 59963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Parser parser(script, parsing_flags, NULL, NULL); 59973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (info->shared_info()->is_function()) { 59983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = parser.ParseLazy(info); 59993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 60003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = parser.ParseProgram(info); 60013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 60024515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } else { 6003f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ScriptDataImpl* pre_data = info->pre_parse_data(); 60043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Parser parser(script, parsing_flags, info->extension(), pre_data); 6005f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (pre_data != NULL && pre_data->has_error()) { 6006f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Scanner::Location loc = pre_data->MessageLocation(); 6007f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const char* message = pre_data->BuildMessage(); 6008f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Vector<const char*> args = pre_data->BuildArgs(); 6009f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch parser.ReportMessageAt(loc, message, args); 6010f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DeleteArray(message); 6011f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0; i < args.length(); i++) { 6012f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DeleteArray(args[i]); 6013f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 6014f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DeleteArray(args.start()); 601544f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(info->isolate()->has_pending_exception()); 6016f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } else { 60173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result = parser.ParseProgram(info); 6018f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 60194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 6020f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info->SetFunction(result); 6021f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return (result != NULL); 6022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 6025