Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 | 81 |
| 82 private: | 82 private: |
| 83 Element* top() { return top_; } | 83 Element* top() { return top_; } |
| 84 void set_top(Element* value) { top_ = value; } | 84 void set_top(Element* value) { top_ = value; } |
| 85 Element* top_; | 85 Element* top_; |
| 86 bool* ok_; | 86 bool* ok_; |
| 87 }; | 87 }; |
| 88 | 88 |
| 89 | 89 |
| 90 RegExpBuilder::RegExpBuilder() | 90 RegExpBuilder::RegExpBuilder() |
| 91 : pending_empty_(false), | 91 : zone_(Isolate::Current()->zone()), |
| 92 characters_(NULL), | 92 pending_empty_(false), |
| 93 terms_(), | 93 characters_(NULL), |
| 94 alternatives_() | 94 terms_(), |
| 95 alternatives_() | |
| 95 #ifdef DEBUG | 96 #ifdef DEBUG |
| 96 , last_added_(ADD_NONE) | 97 , last_added_(ADD_NONE) |
| 97 #endif | 98 #endif |
| 98 {} | 99 {} |
| 99 | 100 |
| 100 | 101 |
| 101 void RegExpBuilder::FlushCharacters() { | 102 void RegExpBuilder::FlushCharacters() { |
| 102 pending_empty_ = false; | 103 pending_empty_ = false; |
| 103 if (characters_ != NULL) { | 104 if (characters_ != NULL) { |
| 104 RegExpTree* atom = new RegExpAtom(characters_->ToConstVector()); | 105 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector()); |
|
Mads Ager (chromium)
2011/04/01 17:08:38
We have to decide whether we want a space between
| |
| 105 characters_ = NULL; | 106 characters_ = NULL; |
| 106 text_.Add(atom); | 107 text_.Add(atom); |
| 107 LAST(ADD_ATOM); | 108 LAST(ADD_ATOM); |
| 108 } | 109 } |
| 109 } | 110 } |
| 110 | 111 |
| 111 | 112 |
| 112 void RegExpBuilder::FlushText() { | 113 void RegExpBuilder::FlushText() { |
| 113 FlushCharacters(); | 114 FlushCharacters(); |
| 114 int num_text = text_.length(); | 115 int num_text = text_.length(); |
| 115 if (num_text == 0) { | 116 if (num_text == 0) { |
| 116 return; | 117 return; |
| 117 } else if (num_text == 1) { | 118 } else if (num_text == 1) { |
| 118 terms_.Add(text_.last()); | 119 terms_.Add(text_.last()); |
| 119 } else { | 120 } else { |
| 120 RegExpText* text = new RegExpText(); | 121 RegExpText* text = new(zone()) RegExpText(); |
| 121 for (int i = 0; i < num_text; i++) | 122 for (int i = 0; i < num_text; i++) |
| 122 text_.Get(i)->AppendToText(text); | 123 text_.Get(i)->AppendToText(text); |
| 123 terms_.Add(text); | 124 terms_.Add(text); |
| 124 } | 125 } |
| 125 text_.Clear(); | 126 text_.Clear(); |
| 126 } | 127 } |
| 127 | 128 |
| 128 | 129 |
| 129 void RegExpBuilder::AddCharacter(uc16 c) { | 130 void RegExpBuilder::AddCharacter(uc16 c) { |
| 130 pending_empty_ = false; | 131 pending_empty_ = false; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 | 172 |
| 172 void RegExpBuilder::FlushTerms() { | 173 void RegExpBuilder::FlushTerms() { |
| 173 FlushText(); | 174 FlushText(); |
| 174 int num_terms = terms_.length(); | 175 int num_terms = terms_.length(); |
| 175 RegExpTree* alternative; | 176 RegExpTree* alternative; |
| 176 if (num_terms == 0) { | 177 if (num_terms == 0) { |
| 177 alternative = RegExpEmpty::GetInstance(); | 178 alternative = RegExpEmpty::GetInstance(); |
| 178 } else if (num_terms == 1) { | 179 } else if (num_terms == 1) { |
| 179 alternative = terms_.last(); | 180 alternative = terms_.last(); |
| 180 } else { | 181 } else { |
| 181 alternative = new RegExpAlternative(terms_.GetList()); | 182 alternative = new(zone()) RegExpAlternative(terms_.GetList()); |
| 182 } | 183 } |
| 183 alternatives_.Add(alternative); | 184 alternatives_.Add(alternative); |
| 184 terms_.Clear(); | 185 terms_.Clear(); |
| 185 LAST(ADD_NONE); | 186 LAST(ADD_NONE); |
| 186 } | 187 } |
| 187 | 188 |
| 188 | 189 |
| 189 RegExpTree* RegExpBuilder::ToRegExp() { | 190 RegExpTree* RegExpBuilder::ToRegExp() { |
| 190 FlushTerms(); | 191 FlushTerms(); |
| 191 int num_alternatives = alternatives_.length(); | 192 int num_alternatives = alternatives_.length(); |
| 192 if (num_alternatives == 0) { | 193 if (num_alternatives == 0) { |
| 193 return RegExpEmpty::GetInstance(); | 194 return RegExpEmpty::GetInstance(); |
| 194 } | 195 } |
| 195 if (num_alternatives == 1) { | 196 if (num_alternatives == 1) { |
| 196 return alternatives_.last(); | 197 return alternatives_.last(); |
| 197 } | 198 } |
| 198 return new RegExpDisjunction(alternatives_.GetList()); | 199 return new(zone()) RegExpDisjunction(alternatives_.GetList()); |
| 199 } | 200 } |
| 200 | 201 |
| 201 | 202 |
| 202 void RegExpBuilder::AddQuantifierToAtom(int min, | 203 void RegExpBuilder::AddQuantifierToAtom(int min, |
| 203 int max, | 204 int max, |
| 204 RegExpQuantifier::Type type) { | 205 RegExpQuantifier::Type type) { |
| 205 if (pending_empty_) { | 206 if (pending_empty_) { |
| 206 pending_empty_ = false; | 207 pending_empty_ = false; |
| 207 return; | 208 return; |
| 208 } | 209 } |
| 209 RegExpTree* atom; | 210 RegExpTree* atom; |
| 210 if (characters_ != NULL) { | 211 if (characters_ != NULL) { |
| 211 ASSERT(last_added_ == ADD_CHAR); | 212 ASSERT(last_added_ == ADD_CHAR); |
| 212 // Last atom was character. | 213 // Last atom was character. |
| 213 Vector<const uc16> char_vector = characters_->ToConstVector(); | 214 Vector<const uc16> char_vector = characters_->ToConstVector(); |
| 214 int num_chars = char_vector.length(); | 215 int num_chars = char_vector.length(); |
| 215 if (num_chars > 1) { | 216 if (num_chars > 1) { |
| 216 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1); | 217 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1); |
| 217 text_.Add(new RegExpAtom(prefix)); | 218 text_.Add(new(zone()) RegExpAtom(prefix)); |
| 218 char_vector = char_vector.SubVector(num_chars - 1, num_chars); | 219 char_vector = char_vector.SubVector(num_chars - 1, num_chars); |
| 219 } | 220 } |
| 220 characters_ = NULL; | 221 characters_ = NULL; |
| 221 atom = new RegExpAtom(char_vector); | 222 atom = new(zone()) RegExpAtom(char_vector); |
| 222 FlushText(); | 223 FlushText(); |
| 223 } else if (text_.length() > 0) { | 224 } else if (text_.length() > 0) { |
| 224 ASSERT(last_added_ == ADD_ATOM); | 225 ASSERT(last_added_ == ADD_ATOM); |
| 225 atom = text_.RemoveLast(); | 226 atom = text_.RemoveLast(); |
| 226 FlushText(); | 227 FlushText(); |
| 227 } else if (terms_.length() > 0) { | 228 } else if (terms_.length() > 0) { |
| 228 ASSERT(last_added_ == ADD_ATOM); | 229 ASSERT(last_added_ == ADD_ATOM); |
| 229 atom = terms_.RemoveLast(); | 230 atom = terms_.RemoveLast(); |
| 230 if (atom->max_match() == 0) { | 231 if (atom->max_match() == 0) { |
| 231 // Guaranteed to only match an empty string. | 232 // Guaranteed to only match an empty string. |
| 232 LAST(ADD_TERM); | 233 LAST(ADD_TERM); |
| 233 if (min == 0) { | 234 if (min == 0) { |
| 234 return; | 235 return; |
| 235 } | 236 } |
| 236 terms_.Add(atom); | 237 terms_.Add(atom); |
| 237 return; | 238 return; |
| 238 } | 239 } |
| 239 } else { | 240 } else { |
| 240 // Only call immediately after adding an atom or character! | 241 // Only call immediately after adding an atom or character! |
| 241 UNREACHABLE(); | 242 UNREACHABLE(); |
| 242 return; | 243 return; |
| 243 } | 244 } |
| 244 terms_.Add(new RegExpQuantifier(min, max, type, atom)); | 245 terms_.Add(new(zone()) RegExpQuantifier(min, max, type, atom)); |
| 245 LAST(ADD_TERM); | 246 LAST(ADD_TERM); |
| 246 } | 247 } |
| 247 | 248 |
| 248 | 249 |
| 249 Handle<String> Parser::LookupSymbol(int symbol_id) { | 250 Handle<String> Parser::LookupSymbol(int symbol_id) { |
| 250 // Length of symbol cache is the number of identified symbols. | 251 // Length of symbol cache is the number of identified symbols. |
| 251 // If we are larger than that, or negative, it's not a cached symbol. | 252 // If we are larger than that, or negative, it's not a cached symbol. |
| 252 // This might also happen if there is no preparser symbol data, even | 253 // This might also happen if there is no preparser symbol data, even |
| 253 // if there is some preparser data. | 254 // if there is some preparser data. |
| 254 if (static_cast<unsigned>(symbol_id) | 255 if (static_cast<unsigned>(symbol_id) |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 return store_[PreparseDataConstants::kHeaderSize + position]; | 402 return store_[PreparseDataConstants::kHeaderSize + position]; |
| 402 } | 403 } |
| 403 | 404 |
| 404 | 405 |
| 405 unsigned* ScriptDataImpl::ReadAddress(int position) { | 406 unsigned* ScriptDataImpl::ReadAddress(int position) { |
| 406 return &store_[PreparseDataConstants::kHeaderSize + position]; | 407 return &store_[PreparseDataConstants::kHeaderSize + position]; |
| 407 } | 408 } |
| 408 | 409 |
| 409 | 410 |
| 410 Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) { | 411 Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) { |
| 411 Scope* result = new Scope(parent, type); | 412 Scope* result = new(zone()) Scope(parent, type); |
| 412 result->Initialize(inside_with); | 413 result->Initialize(inside_with); |
| 413 return result; | 414 return result; |
| 414 } | 415 } |
| 415 | 416 |
| 416 // ---------------------------------------------------------------------------- | 417 // ---------------------------------------------------------------------------- |
| 417 // Target is a support class to facilitate manipulation of the | 418 // Target is a support class to facilitate manipulation of the |
| 418 // Parser's target_stack_ (the stack of potential 'break' and | 419 // Parser's target_stack_ (the stack of potential 'break' and |
| 419 // 'continue' statement targets). Upon construction, a new target is | 420 // 'continue' statement targets). Upon construction, a new target is |
| 420 // added; it is removed upon destruction. | 421 // added; it is removed upon destruction. |
| 421 | 422 |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 594 } | 595 } |
| 595 | 596 |
| 596 | 597 |
| 597 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 598 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
| 598 bool in_global_context, | 599 bool in_global_context, |
| 599 StrictModeFlag strict_mode) { | 600 StrictModeFlag strict_mode) { |
| 600 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 601 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
| 601 | 602 |
| 602 HistogramTimerScope timer(isolate()->counters()->parse()); | 603 HistogramTimerScope timer(isolate()->counters()->parse()); |
| 603 isolate()->counters()->total_parse_size()->Increment(source->length()); | 604 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 604 fni_ = new FuncNameInferrer(); | 605 fni_ = new(zone()) FuncNameInferrer(); |
| 605 | 606 |
| 606 // Initialize parser state. | 607 // Initialize parser state. |
| 607 source->TryFlatten(); | 608 source->TryFlatten(); |
| 608 if (source->IsExternalTwoByteString()) { | 609 if (source->IsExternalTwoByteString()) { |
| 609 // Notice that the stream is destroyed at the end of the branch block. | 610 // Notice that the stream is destroyed at the end of the branch block. |
| 610 // The last line of the blocks can't be moved outside, even though they're | 611 // The last line of the blocks can't be moved outside, even though they're |
| 611 // identical calls. | 612 // identical calls. |
| 612 ExternalTwoByteStringUC16CharacterStream stream( | 613 ExternalTwoByteStringUC16CharacterStream stream( |
| 613 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 614 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
| 614 scanner_.Initialize(&stream); | 615 scanner_.Initialize(&stream); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 645 top_scope_->EnableStrictMode(); | 646 top_scope_->EnableStrictMode(); |
| 646 } | 647 } |
| 647 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); | 648 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); |
| 648 bool ok = true; | 649 bool ok = true; |
| 649 int beg_loc = scanner().location().beg_pos; | 650 int beg_loc = scanner().location().beg_pos; |
| 650 ParseSourceElements(body, Token::EOS, &ok); | 651 ParseSourceElements(body, Token::EOS, &ok); |
| 651 if (ok && top_scope_->is_strict_mode()) { | 652 if (ok && top_scope_->is_strict_mode()) { |
| 652 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 653 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 653 } | 654 } |
| 654 if (ok) { | 655 if (ok) { |
| 655 result = new FunctionLiteral( | 656 result = new(zone()) FunctionLiteral( |
| 656 no_name, | 657 no_name, |
| 657 top_scope_, | 658 top_scope_, |
| 658 body, | 659 body, |
| 659 lexical_scope.materialized_literal_count(), | 660 lexical_scope.materialized_literal_count(), |
| 660 lexical_scope.expected_property_count(), | 661 lexical_scope.expected_property_count(), |
| 661 lexical_scope.only_simple_this_property_assignments(), | 662 lexical_scope.only_simple_this_property_assignments(), |
| 662 lexical_scope.this_property_assignments(), | 663 lexical_scope.this_property_assignments(), |
| 663 0, | 664 0, |
| 664 0, | 665 0, |
| 665 source->length(), | 666 source->length(), |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 706 | 707 |
| 707 | 708 |
| 708 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, | 709 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, |
| 709 UC16CharacterStream* source, | 710 UC16CharacterStream* source, |
| 710 ZoneScope* zone_scope) { | 711 ZoneScope* zone_scope) { |
| 711 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 712 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
| 712 scanner_.Initialize(source); | 713 scanner_.Initialize(source); |
| 713 ASSERT(target_stack_ == NULL); | 714 ASSERT(target_stack_ == NULL); |
| 714 | 715 |
| 715 Handle<String> name(String::cast(shared_info->name())); | 716 Handle<String> name(String::cast(shared_info->name())); |
| 716 fni_ = new FuncNameInferrer(); | 717 fni_ = new(zone()) FuncNameInferrer(); |
| 717 fni_->PushEnclosingName(name); | 718 fni_->PushEnclosingName(name); |
| 718 | 719 |
| 719 mode_ = PARSE_EAGERLY; | 720 mode_ = PARSE_EAGERLY; |
| 720 | 721 |
| 721 // Place holder for the result. | 722 // Place holder for the result. |
| 722 FunctionLiteral* result = NULL; | 723 FunctionLiteral* result = NULL; |
| 723 | 724 |
| 724 { | 725 { |
| 725 // Parse the function literal. | 726 // Parse the function literal. |
| 726 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 727 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1245 case Token::THROW: | 1246 case Token::THROW: |
| 1246 stmt = ParseThrowStatement(ok); | 1247 stmt = ParseThrowStatement(ok); |
| 1247 break; | 1248 break; |
| 1248 | 1249 |
| 1249 case Token::TRY: { | 1250 case Token::TRY: { |
| 1250 // NOTE: It is somewhat complicated to have labels on | 1251 // NOTE: It is somewhat complicated to have labels on |
| 1251 // try-statements. When breaking out of a try-finally statement, | 1252 // try-statements. When breaking out of a try-finally statement, |
| 1252 // one must take great care not to treat it as a | 1253 // one must take great care not to treat it as a |
| 1253 // fall-through. It is much easier just to wrap the entire | 1254 // fall-through. It is much easier just to wrap the entire |
| 1254 // try-statement in a statement block and put the labels there | 1255 // try-statement in a statement block and put the labels there |
| 1255 Block* result = new Block(labels, 1, false); | 1256 Block* result = new(zone()) Block(labels, 1, false); |
| 1256 Target target(&this->target_stack_, result); | 1257 Target target(&this->target_stack_, result); |
| 1257 TryStatement* statement = ParseTryStatement(CHECK_OK); | 1258 TryStatement* statement = ParseTryStatement(CHECK_OK); |
| 1258 if (statement) { | 1259 if (statement) { |
| 1259 statement->set_statement_pos(statement_pos); | 1260 statement->set_statement_pos(statement_pos); |
| 1260 } | 1261 } |
| 1261 if (result) result->AddStatement(statement); | 1262 if (result) result->AddStatement(statement); |
| 1262 return result; | 1263 return result; |
| 1263 } | 1264 } |
| 1264 | 1265 |
| 1265 case Token::FUNCTION: { | 1266 case Token::FUNCTION: { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1343 // parameters) if the proxy is needed or not. The proxy will be | 1344 // parameters) if the proxy is needed or not. The proxy will be |
| 1344 // bound during variable resolution time unless it was pre-bound | 1345 // bound during variable resolution time unless it was pre-bound |
| 1345 // below. | 1346 // below. |
| 1346 // | 1347 // |
| 1347 // WARNING: This will lead to multiple declaration nodes for the | 1348 // WARNING: This will lead to multiple declaration nodes for the |
| 1348 // same variable if it is declared several times. This is not a | 1349 // same variable if it is declared several times. This is not a |
| 1349 // semantic issue as long as we keep the source order, but it may be | 1350 // semantic issue as long as we keep the source order, but it may be |
| 1350 // a performance issue since it may lead to repeated | 1351 // a performance issue since it may lead to repeated |
| 1351 // Runtime::DeclareContextSlot() calls. | 1352 // Runtime::DeclareContextSlot() calls. |
| 1352 VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with()); | 1353 VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with()); |
| 1353 top_scope_->AddDeclaration(new Declaration(proxy, mode, fun)); | 1354 top_scope_->AddDeclaration(new(zone()) Declaration(proxy, mode, fun)); |
| 1354 | 1355 |
| 1355 // For global const variables we bind the proxy to a variable. | 1356 // For global const variables we bind the proxy to a variable. |
| 1356 if (mode == Variable::CONST && top_scope_->is_global_scope()) { | 1357 if (mode == Variable::CONST && top_scope_->is_global_scope()) { |
| 1357 ASSERT(resolve); // should be set by all callers | 1358 ASSERT(resolve); // should be set by all callers |
| 1358 Variable::Kind kind = Variable::NORMAL; | 1359 Variable::Kind kind = Variable::NORMAL; |
| 1359 var = new Variable(top_scope_, name, Variable::CONST, true, kind); | 1360 var = new(zone()) Variable(top_scope_, name, Variable::CONST, true, kind); |
| 1360 } | 1361 } |
| 1361 | 1362 |
| 1362 // If requested and we have a local variable, bind the proxy to the variable | 1363 // If requested and we have a local variable, bind the proxy to the variable |
| 1363 // at parse-time. This is used for functions (and consts) declared inside | 1364 // at parse-time. This is used for functions (and consts) declared inside |
| 1364 // statements: the corresponding function (or const) variable must be in the | 1365 // statements: the corresponding function (or const) variable must be in the |
| 1365 // function scope and not a statement-local scope, e.g. as provided with a | 1366 // function scope and not a statement-local scope, e.g. as provided with a |
| 1366 // 'with' statement: | 1367 // 'with' statement: |
| 1367 // | 1368 // |
| 1368 // with (obj) { | 1369 // with (obj) { |
| 1369 // function f() {} | 1370 // function f() {} |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1437 shared->set_construct_stub(*construct_stub); | 1438 shared->set_construct_stub(*construct_stub); |
| 1438 | 1439 |
| 1439 // Copy the function data to the shared function info. | 1440 // Copy the function data to the shared function info. |
| 1440 shared->set_function_data(fun->shared()->function_data()); | 1441 shared->set_function_data(fun->shared()->function_data()); |
| 1441 int parameters = fun->shared()->formal_parameter_count(); | 1442 int parameters = fun->shared()->formal_parameter_count(); |
| 1442 shared->set_formal_parameter_count(parameters); | 1443 shared->set_formal_parameter_count(parameters); |
| 1443 | 1444 |
| 1444 // TODO(1240846): It's weird that native function declarations are | 1445 // TODO(1240846): It's weird that native function declarations are |
| 1445 // introduced dynamically when we meet their declarations, whereas | 1446 // introduced dynamically when we meet their declarations, whereas |
| 1446 // other functions are setup when entering the surrounding scope. | 1447 // other functions are setup when entering the surrounding scope. |
| 1447 SharedFunctionInfoLiteral* lit = new SharedFunctionInfoLiteral(shared); | 1448 SharedFunctionInfoLiteral* lit = |
| 1449 new(zone()) SharedFunctionInfoLiteral(shared); | |
| 1448 VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK); | 1450 VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK); |
| 1449 return new ExpressionStatement( | 1451 return new(zone()) ExpressionStatement(new(zone()) Assignment( |
| 1450 new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); | 1452 Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); |
| 1451 } | 1453 } |
| 1452 | 1454 |
| 1453 | 1455 |
| 1454 Statement* Parser::ParseFunctionDeclaration(bool* ok) { | 1456 Statement* Parser::ParseFunctionDeclaration(bool* ok) { |
| 1455 // FunctionDeclaration :: | 1457 // FunctionDeclaration :: |
| 1456 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1458 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1457 Expect(Token::FUNCTION, CHECK_OK); | 1459 Expect(Token::FUNCTION, CHECK_OK); |
| 1458 int function_token_position = scanner().location().beg_pos; | 1460 int function_token_position = scanner().location().beg_pos; |
| 1459 bool is_reserved = false; | 1461 bool is_reserved = false; |
| 1460 Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK); | 1462 Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1472 | 1474 |
| 1473 | 1475 |
| 1474 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1476 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| 1475 // Block :: | 1477 // Block :: |
| 1476 // '{' Statement* '}' | 1478 // '{' Statement* '}' |
| 1477 | 1479 |
| 1478 // Note that a Block does not introduce a new execution scope! | 1480 // Note that a Block does not introduce a new execution scope! |
| 1479 // (ECMA-262, 3rd, 12.2) | 1481 // (ECMA-262, 3rd, 12.2) |
| 1480 // | 1482 // |
| 1481 // Construct block expecting 16 statements. | 1483 // Construct block expecting 16 statements. |
| 1482 Block* result = new Block(labels, 16, false); | 1484 Block* result = new(zone()) Block(labels, 16, false); |
| 1483 Target target(&this->target_stack_, result); | 1485 Target target(&this->target_stack_, result); |
| 1484 Expect(Token::LBRACE, CHECK_OK); | 1486 Expect(Token::LBRACE, CHECK_OK); |
| 1485 while (peek() != Token::RBRACE) { | 1487 while (peek() != Token::RBRACE) { |
| 1486 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1488 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 1487 if (stat && !stat->IsEmpty()) result->AddStatement(stat); | 1489 if (stat && !stat->IsEmpty()) result->AddStatement(stat); |
| 1488 } | 1490 } |
| 1489 Expect(Token::RBRACE, CHECK_OK); | 1491 Expect(Token::RBRACE, CHECK_OK); |
| 1490 return result; | 1492 return result; |
| 1491 } | 1493 } |
| 1492 | 1494 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1542 // Scope declaration, and rewrite the source-level initialization into an | 1544 // Scope declaration, and rewrite the source-level initialization into an |
| 1543 // assignment statement. We use a block to collect multiple assignments. | 1545 // assignment statement. We use a block to collect multiple assignments. |
| 1544 // | 1546 // |
| 1545 // We mark the block as initializer block because we don't want the | 1547 // We mark the block as initializer block because we don't want the |
| 1546 // rewriter to add a '.result' assignment to such a block (to get compliant | 1548 // rewriter to add a '.result' assignment to such a block (to get compliant |
| 1547 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 1549 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
| 1548 // reasons when pretty-printing. Also, unless an assignment (initialization) | 1550 // reasons when pretty-printing. Also, unless an assignment (initialization) |
| 1549 // is inside an initializer block, it is ignored. | 1551 // is inside an initializer block, it is ignored. |
| 1550 // | 1552 // |
| 1551 // Create new block with one expected declaration. | 1553 // Create new block with one expected declaration. |
| 1552 Block* block = new Block(NULL, 1, true); | 1554 Block* block = new(zone()) Block(NULL, 1, true); |
| 1553 VariableProxy* last_var = NULL; // the last variable declared | 1555 VariableProxy* last_var = NULL; // the last variable declared |
| 1554 int nvars = 0; // the number of variables declared | 1556 int nvars = 0; // the number of variables declared |
| 1555 do { | 1557 do { |
| 1556 if (fni_ != NULL) fni_->Enter(); | 1558 if (fni_ != NULL) fni_->Enter(); |
| 1557 | 1559 |
| 1558 // Parse variable name. | 1560 // Parse variable name. |
| 1559 if (nvars > 0) Consume(Token::COMMA); | 1561 if (nvars > 0) Consume(Token::COMMA); |
| 1560 Handle<String> name = ParseIdentifier(CHECK_OK); | 1562 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1561 if (fni_ != NULL) fni_->PushVariableName(name); | 1563 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1562 | 1564 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1643 // variable defined in the global object and not in any | 1645 // variable defined in the global object and not in any |
| 1644 // prototype. This way, global variable declarations can shadow | 1646 // prototype. This way, global variable declarations can shadow |
| 1645 // properties in the prototype chain, but only after the variable | 1647 // properties in the prototype chain, but only after the variable |
| 1646 // declaration statement has been executed. This is important in | 1648 // declaration statement has been executed. This is important in |
| 1647 // browsers where the global object (window) has lots of | 1649 // browsers where the global object (window) has lots of |
| 1648 // properties defined in prototype objects. | 1650 // properties defined in prototype objects. |
| 1649 | 1651 |
| 1650 if (top_scope_->is_global_scope()) { | 1652 if (top_scope_->is_global_scope()) { |
| 1651 // Compute the arguments for the runtime call. | 1653 // Compute the arguments for the runtime call. |
| 1652 ZoneList<Expression*>* arguments = new ZoneList<Expression*>(3); | 1654 ZoneList<Expression*>* arguments = new ZoneList<Expression*>(3); |
| 1653 arguments->Add(new Literal(name)); // we have at least 1 parameter | 1655 // We have at least 1 parameter. |
| 1656 arguments->Add(new(zone()) Literal(name)); | |
| 1654 CallRuntime* initialize; | 1657 CallRuntime* initialize; |
| 1655 | 1658 |
| 1656 if (is_const) { | 1659 if (is_const) { |
| 1657 arguments->Add(value); | 1660 arguments->Add(value); |
| 1658 value = NULL; // zap the value to avoid the unnecessary assignment | 1661 value = NULL; // zap the value to avoid the unnecessary assignment |
| 1659 | 1662 |
| 1660 // Construct the call to Runtime_InitializeConstGlobal | 1663 // Construct the call to Runtime_InitializeConstGlobal |
| 1661 // and add it to the initialization statement block. | 1664 // and add it to the initialization statement block. |
| 1662 // Note that the function does different things depending on | 1665 // Note that the function does different things depending on |
| 1663 // the number of arguments (1 or 2). | 1666 // the number of arguments (1 or 2). |
| 1664 initialize = | 1667 initialize = |
| 1665 new CallRuntime( | 1668 new(zone()) CallRuntime( |
| 1666 isolate()->factory()->InitializeConstGlobal_symbol(), | 1669 isolate()->factory()->InitializeConstGlobal_symbol(), |
| 1667 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), | 1670 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
| 1668 arguments); | 1671 arguments); |
| 1669 } else { | 1672 } else { |
| 1670 // Add strict mode. | 1673 // Add strict mode. |
| 1671 // We may want to pass singleton to avoid Literal allocations. | 1674 // We may want to pass singleton to avoid Literal allocations. |
| 1672 arguments->Add(NewNumberLiteral( | 1675 arguments->Add(NewNumberLiteral( |
| 1673 top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode)); | 1676 top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode)); |
| 1674 | 1677 |
| 1675 // Be careful not to assign a value to the global variable if | 1678 // Be careful not to assign a value to the global variable if |
| 1676 // we're in a with. The initialization value should not | 1679 // we're in a with. The initialization value should not |
| 1677 // necessarily be stored in the global object in that case, | 1680 // necessarily be stored in the global object in that case, |
| 1678 // which is why we need to generate a separate assignment node. | 1681 // which is why we need to generate a separate assignment node. |
| 1679 if (value != NULL && !inside_with()) { | 1682 if (value != NULL && !inside_with()) { |
| 1680 arguments->Add(value); | 1683 arguments->Add(value); |
| 1681 value = NULL; // zap the value to avoid the unnecessary assignment | 1684 value = NULL; // zap the value to avoid the unnecessary assignment |
| 1682 } | 1685 } |
| 1683 | 1686 |
| 1684 // Construct the call to Runtime_InitializeVarGlobal | 1687 // Construct the call to Runtime_InitializeVarGlobal |
| 1685 // and add it to the initialization statement block. | 1688 // and add it to the initialization statement block. |
| 1686 // Note that the function does different things depending on | 1689 // Note that the function does different things depending on |
| 1687 // the number of arguments (2 or 3). | 1690 // the number of arguments (2 or 3). |
| 1688 initialize = | 1691 initialize = |
| 1689 new CallRuntime( | 1692 new(zone()) CallRuntime( |
| 1690 isolate()->factory()->InitializeVarGlobal_symbol(), | 1693 isolate()->factory()->InitializeVarGlobal_symbol(), |
| 1691 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | 1694 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
| 1692 arguments); | 1695 arguments); |
| 1693 } | 1696 } |
| 1694 | 1697 |
| 1695 block->AddStatement(new ExpressionStatement(initialize)); | 1698 block->AddStatement(new(zone()) ExpressionStatement(initialize)); |
| 1696 } | 1699 } |
| 1697 | 1700 |
| 1698 // Add an assignment node to the initialization statement block if | 1701 // Add an assignment node to the initialization statement block if |
| 1699 // we still have a pending initialization value. We must distinguish | 1702 // we still have a pending initialization value. We must distinguish |
| 1700 // between variables and constants: Variable initializations are simply | 1703 // between variables and constants: Variable initializations are simply |
| 1701 // assignments (with all the consequences if they are inside a 'with' | 1704 // assignments (with all the consequences if they are inside a 'with' |
| 1702 // statement - they may change a 'with' object property). Constant | 1705 // statement - they may change a 'with' object property). Constant |
| 1703 // initializations always assign to the declared constant which is | 1706 // initializations always assign to the declared constant which is |
| 1704 // always at the function scope level. This is only relevant for | 1707 // always at the function scope level. This is only relevant for |
| 1705 // dynamically looked-up variables and constants (the start context | 1708 // dynamically looked-up variables and constants (the start context |
| 1706 // for constant lookups is always the function context, while it is | 1709 // for constant lookups is always the function context, while it is |
| 1707 // the top context for variables). Sigh... | 1710 // the top context for variables). Sigh... |
| 1708 if (value != NULL) { | 1711 if (value != NULL) { |
| 1709 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR); | 1712 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR); |
| 1710 Assignment* assignment = new Assignment(op, last_var, value, position); | 1713 Assignment* assignment = |
| 1711 if (block) block->AddStatement(new ExpressionStatement(assignment)); | 1714 new(zone()) Assignment(op, last_var, value, position); |
| 1715 if (block) { | |
| 1716 block->AddStatement(new(zone()) ExpressionStatement(assignment)); | |
| 1717 } | |
| 1712 } | 1718 } |
| 1713 | 1719 |
| 1714 if (fni_ != NULL) fni_->Leave(); | 1720 if (fni_ != NULL) fni_->Leave(); |
| 1715 } while (peek() == Token::COMMA); | 1721 } while (peek() == Token::COMMA); |
| 1716 | 1722 |
| 1717 if (!is_const && nvars == 1) { | 1723 if (!is_const && nvars == 1) { |
| 1718 // We have a single, non-const variable. | 1724 // We have a single, non-const variable. |
| 1719 ASSERT(last_var != NULL); | 1725 ASSERT(last_var != NULL); |
| 1720 *var = last_var; | 1726 *var = last_var; |
| 1721 } | 1727 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1767 // Remove the "ghost" variable that turned out to be a label | 1773 // Remove the "ghost" variable that turned out to be a label |
| 1768 // from the top scope. This way, we don't try to resolve it | 1774 // from the top scope. This way, we don't try to resolve it |
| 1769 // during the scope processing. | 1775 // during the scope processing. |
| 1770 top_scope_->RemoveUnresolved(var); | 1776 top_scope_->RemoveUnresolved(var); |
| 1771 Expect(Token::COLON, CHECK_OK); | 1777 Expect(Token::COLON, CHECK_OK); |
| 1772 return ParseStatement(labels, ok); | 1778 return ParseStatement(labels, ok); |
| 1773 } | 1779 } |
| 1774 | 1780 |
| 1775 // Parsed expression statement. | 1781 // Parsed expression statement. |
| 1776 ExpectSemicolon(CHECK_OK); | 1782 ExpectSemicolon(CHECK_OK); |
| 1777 return new ExpressionStatement(expr); | 1783 return new(zone()) ExpressionStatement(expr); |
| 1778 } | 1784 } |
| 1779 | 1785 |
| 1780 | 1786 |
| 1781 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { | 1787 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
| 1782 // IfStatement :: | 1788 // IfStatement :: |
| 1783 // 'if' '(' Expression ')' Statement ('else' Statement)? | 1789 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 1784 | 1790 |
| 1785 Expect(Token::IF, CHECK_OK); | 1791 Expect(Token::IF, CHECK_OK); |
| 1786 Expect(Token::LPAREN, CHECK_OK); | 1792 Expect(Token::LPAREN, CHECK_OK); |
| 1787 Expression* condition = ParseExpression(true, CHECK_OK); | 1793 Expression* condition = ParseExpression(true, CHECK_OK); |
| 1788 Expect(Token::RPAREN, CHECK_OK); | 1794 Expect(Token::RPAREN, CHECK_OK); |
| 1789 Statement* then_statement = ParseStatement(labels, CHECK_OK); | 1795 Statement* then_statement = ParseStatement(labels, CHECK_OK); |
| 1790 Statement* else_statement = NULL; | 1796 Statement* else_statement = NULL; |
| 1791 if (peek() == Token::ELSE) { | 1797 if (peek() == Token::ELSE) { |
| 1792 Next(); | 1798 Next(); |
| 1793 else_statement = ParseStatement(labels, CHECK_OK); | 1799 else_statement = ParseStatement(labels, CHECK_OK); |
| 1794 } else { | 1800 } else { |
| 1795 else_statement = EmptyStatement(); | 1801 else_statement = EmptyStatement(); |
| 1796 } | 1802 } |
| 1797 return new IfStatement(condition, then_statement, else_statement); | 1803 return new(zone()) IfStatement(condition, then_statement, else_statement); |
| 1798 } | 1804 } |
| 1799 | 1805 |
| 1800 | 1806 |
| 1801 Statement* Parser::ParseContinueStatement(bool* ok) { | 1807 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 1802 // ContinueStatement :: | 1808 // ContinueStatement :: |
| 1803 // 'continue' Identifier? ';' | 1809 // 'continue' Identifier? ';' |
| 1804 | 1810 |
| 1805 Expect(Token::CONTINUE, CHECK_OK); | 1811 Expect(Token::CONTINUE, CHECK_OK); |
| 1806 Handle<String> label = Handle<String>::null(); | 1812 Handle<String> label = Handle<String>::null(); |
| 1807 Token::Value tok = peek(); | 1813 Token::Value tok = peek(); |
| 1808 if (!scanner().has_line_terminator_before_next() && | 1814 if (!scanner().has_line_terminator_before_next() && |
| 1809 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 1815 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 1810 label = ParseIdentifier(CHECK_OK); | 1816 label = ParseIdentifier(CHECK_OK); |
| 1811 } | 1817 } |
| 1812 IterationStatement* target = NULL; | 1818 IterationStatement* target = NULL; |
| 1813 target = LookupContinueTarget(label, CHECK_OK); | 1819 target = LookupContinueTarget(label, CHECK_OK); |
| 1814 if (target == NULL) { | 1820 if (target == NULL) { |
| 1815 // Illegal continue statement. | 1821 // Illegal continue statement. |
| 1816 const char* message = "illegal_continue"; | 1822 const char* message = "illegal_continue"; |
| 1817 Vector<Handle<String> > args; | 1823 Vector<Handle<String> > args; |
| 1818 if (!label.is_null()) { | 1824 if (!label.is_null()) { |
| 1819 message = "unknown_label"; | 1825 message = "unknown_label"; |
| 1820 args = Vector<Handle<String> >(&label, 1); | 1826 args = Vector<Handle<String> >(&label, 1); |
| 1821 } | 1827 } |
| 1822 ReportMessageAt(scanner().location(), message, args); | 1828 ReportMessageAt(scanner().location(), message, args); |
| 1823 *ok = false; | 1829 *ok = false; |
| 1824 return NULL; | 1830 return NULL; |
| 1825 } | 1831 } |
| 1826 ExpectSemicolon(CHECK_OK); | 1832 ExpectSemicolon(CHECK_OK); |
| 1827 return new ContinueStatement(target); | 1833 return new(zone()) ContinueStatement(target); |
| 1828 } | 1834 } |
| 1829 | 1835 |
| 1830 | 1836 |
| 1831 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 1837 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| 1832 // BreakStatement :: | 1838 // BreakStatement :: |
| 1833 // 'break' Identifier? ';' | 1839 // 'break' Identifier? ';' |
| 1834 | 1840 |
| 1835 Expect(Token::BREAK, CHECK_OK); | 1841 Expect(Token::BREAK, CHECK_OK); |
| 1836 Handle<String> label; | 1842 Handle<String> label; |
| 1837 Token::Value tok = peek(); | 1843 Token::Value tok = peek(); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1852 Vector<Handle<String> > args; | 1858 Vector<Handle<String> > args; |
| 1853 if (!label.is_null()) { | 1859 if (!label.is_null()) { |
| 1854 message = "unknown_label"; | 1860 message = "unknown_label"; |
| 1855 args = Vector<Handle<String> >(&label, 1); | 1861 args = Vector<Handle<String> >(&label, 1); |
| 1856 } | 1862 } |
| 1857 ReportMessageAt(scanner().location(), message, args); | 1863 ReportMessageAt(scanner().location(), message, args); |
| 1858 *ok = false; | 1864 *ok = false; |
| 1859 return NULL; | 1865 return NULL; |
| 1860 } | 1866 } |
| 1861 ExpectSemicolon(CHECK_OK); | 1867 ExpectSemicolon(CHECK_OK); |
| 1862 return new BreakStatement(target); | 1868 return new(zone()) BreakStatement(target); |
| 1863 } | 1869 } |
| 1864 | 1870 |
| 1865 | 1871 |
| 1866 Statement* Parser::ParseReturnStatement(bool* ok) { | 1872 Statement* Parser::ParseReturnStatement(bool* ok) { |
| 1867 // ReturnStatement :: | 1873 // ReturnStatement :: |
| 1868 // 'return' Expression? ';' | 1874 // 'return' Expression? ';' |
| 1869 | 1875 |
| 1870 // Consume the return token. It is necessary to do the before | 1876 // Consume the return token. It is necessary to do the before |
| 1871 // reporting any errors on it, because of the way errors are | 1877 // reporting any errors on it, because of the way errors are |
| 1872 // reported (underlining). | 1878 // reported (underlining). |
| 1873 Expect(Token::RETURN, CHECK_OK); | 1879 Expect(Token::RETURN, CHECK_OK); |
| 1874 | 1880 |
| 1875 // An ECMAScript program is considered syntactically incorrect if it | 1881 // An ECMAScript program is considered syntactically incorrect if it |
| 1876 // contains a return statement that is not within the body of a | 1882 // contains a return statement that is not within the body of a |
| 1877 // function. See ECMA-262, section 12.9, page 67. | 1883 // function. See ECMA-262, section 12.9, page 67. |
| 1878 // | 1884 // |
| 1879 // To be consistent with KJS we report the syntax error at runtime. | 1885 // To be consistent with KJS we report the syntax error at runtime. |
| 1880 if (!top_scope_->is_function_scope()) { | 1886 if (!top_scope_->is_function_scope()) { |
| 1881 Handle<String> type = isolate()->factory()->illegal_return_symbol(); | 1887 Handle<String> type = isolate()->factory()->illegal_return_symbol(); |
| 1882 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); | 1888 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); |
| 1883 return new ExpressionStatement(throw_error); | 1889 return new(zone()) ExpressionStatement(throw_error); |
| 1884 } | 1890 } |
| 1885 | 1891 |
| 1886 Token::Value tok = peek(); | 1892 Token::Value tok = peek(); |
| 1887 if (scanner().has_line_terminator_before_next() || | 1893 if (scanner().has_line_terminator_before_next() || |
| 1888 tok == Token::SEMICOLON || | 1894 tok == Token::SEMICOLON || |
| 1889 tok == Token::RBRACE || | 1895 tok == Token::RBRACE || |
| 1890 tok == Token::EOS) { | 1896 tok == Token::EOS) { |
| 1891 ExpectSemicolon(CHECK_OK); | 1897 ExpectSemicolon(CHECK_OK); |
| 1892 return new ReturnStatement(GetLiteralUndefined()); | 1898 return new(zone()) ReturnStatement(GetLiteralUndefined()); |
| 1893 } | 1899 } |
| 1894 | 1900 |
| 1895 Expression* expr = ParseExpression(true, CHECK_OK); | 1901 Expression* expr = ParseExpression(true, CHECK_OK); |
| 1896 ExpectSemicolon(CHECK_OK); | 1902 ExpectSemicolon(CHECK_OK); |
| 1897 return new ReturnStatement(expr); | 1903 return new(zone()) ReturnStatement(expr); |
| 1898 } | 1904 } |
| 1899 | 1905 |
| 1900 | 1906 |
| 1901 Block* Parser::WithHelper(Expression* obj, | 1907 Block* Parser::WithHelper(Expression* obj, |
| 1902 ZoneStringList* labels, | 1908 ZoneStringList* labels, |
| 1903 bool is_catch_block, | 1909 bool is_catch_block, |
| 1904 bool* ok) { | 1910 bool* ok) { |
| 1905 // Parse the statement and collect escaping labels. | 1911 // Parse the statement and collect escaping labels. |
| 1906 ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0); | 1912 ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0); |
| 1907 TargetCollector collector(target_list); | 1913 TargetCollector collector(target_list); |
| 1908 Statement* stat; | 1914 Statement* stat; |
| 1909 { Target target(&this->target_stack_, &collector); | 1915 { Target target(&this->target_stack_, &collector); |
| 1910 with_nesting_level_++; | 1916 with_nesting_level_++; |
| 1911 top_scope_->RecordWithStatement(); | 1917 top_scope_->RecordWithStatement(); |
| 1912 stat = ParseStatement(labels, CHECK_OK); | 1918 stat = ParseStatement(labels, CHECK_OK); |
| 1913 with_nesting_level_--; | 1919 with_nesting_level_--; |
| 1914 } | 1920 } |
| 1915 // Create resulting block with two statements. | 1921 // Create resulting block with two statements. |
| 1916 // 1: Evaluate the with expression. | 1922 // 1: Evaluate the with expression. |
| 1917 // 2: The try-finally block evaluating the body. | 1923 // 2: The try-finally block evaluating the body. |
| 1918 Block* result = new Block(NULL, 2, false); | 1924 Block* result = new(zone()) Block(NULL, 2, false); |
| 1919 | 1925 |
| 1920 if (result != NULL) { | 1926 if (result != NULL) { |
| 1921 result->AddStatement(new WithEnterStatement(obj, is_catch_block)); | 1927 result->AddStatement(new(zone()) WithEnterStatement(obj, is_catch_block)); |
| 1922 | 1928 |
| 1923 // Create body block. | 1929 // Create body block. |
| 1924 Block* body = new Block(NULL, 1, false); | 1930 Block* body = new(zone()) Block(NULL, 1, false); |
| 1925 body->AddStatement(stat); | 1931 body->AddStatement(stat); |
| 1926 | 1932 |
| 1927 // Create exit block. | 1933 // Create exit block. |
| 1928 Block* exit = new Block(NULL, 1, false); | 1934 Block* exit = new(zone()) Block(NULL, 1, false); |
| 1929 exit->AddStatement(new WithExitStatement()); | 1935 exit->AddStatement(new(zone()) WithExitStatement()); |
| 1930 | 1936 |
| 1931 // Return a try-finally statement. | 1937 // Return a try-finally statement. |
| 1932 TryFinallyStatement* wrapper = new TryFinallyStatement(body, exit); | 1938 TryFinallyStatement* wrapper = new(zone()) TryFinallyStatement(body, exit); |
| 1933 wrapper->set_escaping_targets(collector.targets()); | 1939 wrapper->set_escaping_targets(collector.targets()); |
| 1934 result->AddStatement(wrapper); | 1940 result->AddStatement(wrapper); |
| 1935 } | 1941 } |
| 1936 return result; | 1942 return result; |
| 1937 } | 1943 } |
| 1938 | 1944 |
| 1939 | 1945 |
| 1940 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 1946 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 1941 // WithStatement :: | 1947 // WithStatement :: |
| 1942 // 'with' '(' Expression ')' Statement | 1948 // 'with' '(' Expression ')' Statement |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1979 Expect(Token::COLON, CHECK_OK); | 1985 Expect(Token::COLON, CHECK_OK); |
| 1980 int pos = scanner().location().beg_pos; | 1986 int pos = scanner().location().beg_pos; |
| 1981 ZoneList<Statement*>* statements = new ZoneList<Statement*>(5); | 1987 ZoneList<Statement*>* statements = new ZoneList<Statement*>(5); |
| 1982 while (peek() != Token::CASE && | 1988 while (peek() != Token::CASE && |
| 1983 peek() != Token::DEFAULT && | 1989 peek() != Token::DEFAULT && |
| 1984 peek() != Token::RBRACE) { | 1990 peek() != Token::RBRACE) { |
| 1985 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1991 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 1986 statements->Add(stat); | 1992 statements->Add(stat); |
| 1987 } | 1993 } |
| 1988 | 1994 |
| 1989 return new CaseClause(label, statements, pos); | 1995 return new(zone()) CaseClause(label, statements, pos); |
| 1990 } | 1996 } |
| 1991 | 1997 |
| 1992 | 1998 |
| 1993 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, | 1999 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, |
| 1994 bool* ok) { | 2000 bool* ok) { |
| 1995 // SwitchStatement :: | 2001 // SwitchStatement :: |
| 1996 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2002 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 1997 | 2003 |
| 1998 SwitchStatement* statement = new SwitchStatement(labels); | 2004 SwitchStatement* statement = new(zone()) SwitchStatement(labels); |
| 1999 Target target(&this->target_stack_, statement); | 2005 Target target(&this->target_stack_, statement); |
| 2000 | 2006 |
| 2001 Expect(Token::SWITCH, CHECK_OK); | 2007 Expect(Token::SWITCH, CHECK_OK); |
| 2002 Expect(Token::LPAREN, CHECK_OK); | 2008 Expect(Token::LPAREN, CHECK_OK); |
| 2003 Expression* tag = ParseExpression(true, CHECK_OK); | 2009 Expression* tag = ParseExpression(true, CHECK_OK); |
| 2004 Expect(Token::RPAREN, CHECK_OK); | 2010 Expect(Token::RPAREN, CHECK_OK); |
| 2005 | 2011 |
| 2006 bool default_seen = false; | 2012 bool default_seen = false; |
| 2007 ZoneList<CaseClause*>* cases = new ZoneList<CaseClause*>(4); | 2013 ZoneList<CaseClause*>* cases = new ZoneList<CaseClause*>(4); |
| 2008 Expect(Token::LBRACE, CHECK_OK); | 2014 Expect(Token::LBRACE, CHECK_OK); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2024 Expect(Token::THROW, CHECK_OK); | 2030 Expect(Token::THROW, CHECK_OK); |
| 2025 int pos = scanner().location().beg_pos; | 2031 int pos = scanner().location().beg_pos; |
| 2026 if (scanner().has_line_terminator_before_next()) { | 2032 if (scanner().has_line_terminator_before_next()) { |
| 2027 ReportMessage("newline_after_throw", Vector<const char*>::empty()); | 2033 ReportMessage("newline_after_throw", Vector<const char*>::empty()); |
| 2028 *ok = false; | 2034 *ok = false; |
| 2029 return NULL; | 2035 return NULL; |
| 2030 } | 2036 } |
| 2031 Expression* exception = ParseExpression(true, CHECK_OK); | 2037 Expression* exception = ParseExpression(true, CHECK_OK); |
| 2032 ExpectSemicolon(CHECK_OK); | 2038 ExpectSemicolon(CHECK_OK); |
| 2033 | 2039 |
| 2034 return new ExpressionStatement(new Throw(exception, pos)); | 2040 return new(zone()) ExpressionStatement(new(zone()) Throw(exception, pos)); |
| 2035 } | 2041 } |
| 2036 | 2042 |
| 2037 | 2043 |
| 2038 TryStatement* Parser::ParseTryStatement(bool* ok) { | 2044 TryStatement* Parser::ParseTryStatement(bool* ok) { |
| 2039 // TryStatement :: | 2045 // TryStatement :: |
| 2040 // 'try' Block Catch | 2046 // 'try' Block Catch |
| 2041 // 'try' Block Finally | 2047 // 'try' Block Finally |
| 2042 // 'try' Block Catch Finally | 2048 // 'try' Block Catch Finally |
| 2043 // | 2049 // |
| 2044 // Catch :: | 2050 // Catch :: |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2088 return NULL; | 2094 return NULL; |
| 2089 } | 2095 } |
| 2090 | 2096 |
| 2091 Expect(Token::RPAREN, CHECK_OK); | 2097 Expect(Token::RPAREN, CHECK_OK); |
| 2092 | 2098 |
| 2093 if (peek() == Token::LBRACE) { | 2099 if (peek() == Token::LBRACE) { |
| 2094 // Allocate a temporary for holding the finally state while | 2100 // Allocate a temporary for holding the finally state while |
| 2095 // executing the finally block. | 2101 // executing the finally block. |
| 2096 catch_var = | 2102 catch_var = |
| 2097 top_scope_->NewTemporary(isolate()->factory()->catch_var_symbol()); | 2103 top_scope_->NewTemporary(isolate()->factory()->catch_var_symbol()); |
| 2098 Literal* name_literal = new Literal(name); | 2104 Literal* name_literal = new(zone()) Literal(name); |
| 2099 VariableProxy* catch_var_use = new VariableProxy(catch_var); | 2105 VariableProxy* catch_var_use = new(zone()) VariableProxy(catch_var); |
| 2100 Expression* obj = new CatchExtensionObject(name_literal, catch_var_use); | 2106 Expression* obj = |
| 2107 new(zone()) CatchExtensionObject(name_literal, catch_var_use); | |
| 2101 { Target target(&this->target_stack_, &catch_collector); | 2108 { Target target(&this->target_stack_, &catch_collector); |
| 2102 catch_block = WithHelper(obj, NULL, true, CHECK_OK); | 2109 catch_block = WithHelper(obj, NULL, true, CHECK_OK); |
| 2103 } | 2110 } |
| 2104 } else { | 2111 } else { |
| 2105 Expect(Token::LBRACE, CHECK_OK); | 2112 Expect(Token::LBRACE, CHECK_OK); |
| 2106 } | 2113 } |
| 2107 | 2114 |
| 2108 tok = peek(); | 2115 tok = peek(); |
| 2109 } | 2116 } |
| 2110 | 2117 |
| 2111 if (tok == Token::FINALLY || !has_catch) { | 2118 if (tok == Token::FINALLY || !has_catch) { |
| 2112 Consume(Token::FINALLY); | 2119 Consume(Token::FINALLY); |
| 2113 // Declare a variable for holding the finally state while | 2120 // Declare a variable for holding the finally state while |
| 2114 // executing the finally block. | 2121 // executing the finally block. |
| 2115 finally_block = ParseBlock(NULL, CHECK_OK); | 2122 finally_block = ParseBlock(NULL, CHECK_OK); |
| 2116 } | 2123 } |
| 2117 | 2124 |
| 2118 // Simplify the AST nodes by converting: | 2125 // Simplify the AST nodes by converting: |
| 2119 // 'try { } catch { } finally { }' | 2126 // 'try { } catch { } finally { }' |
| 2120 // to: | 2127 // to: |
| 2121 // 'try { try { } catch { } } finally { }' | 2128 // 'try { try { } catch { } } finally { }' |
| 2122 | 2129 |
| 2123 if (catch_block != NULL && finally_block != NULL) { | 2130 if (catch_block != NULL && finally_block != NULL) { |
| 2124 VariableProxy* catch_var_defn = new VariableProxy(catch_var); | 2131 VariableProxy* catch_var_defn = new(zone()) VariableProxy(catch_var); |
| 2125 TryCatchStatement* statement = | 2132 TryCatchStatement* statement = |
| 2126 new TryCatchStatement(try_block, catch_var_defn, catch_block); | 2133 new(zone()) TryCatchStatement(try_block, catch_var_defn, catch_block); |
| 2127 statement->set_escaping_targets(collector.targets()); | 2134 statement->set_escaping_targets(collector.targets()); |
| 2128 try_block = new Block(NULL, 1, false); | 2135 try_block = new(zone()) Block(NULL, 1, false); |
| 2129 try_block->AddStatement(statement); | 2136 try_block->AddStatement(statement); |
| 2130 catch_block = NULL; | 2137 catch_block = NULL; |
| 2131 } | 2138 } |
| 2132 | 2139 |
| 2133 TryStatement* result = NULL; | 2140 TryStatement* result = NULL; |
| 2134 if (catch_block != NULL) { | 2141 if (catch_block != NULL) { |
| 2135 ASSERT(finally_block == NULL); | 2142 ASSERT(finally_block == NULL); |
| 2136 VariableProxy* catch_var_defn = new VariableProxy(catch_var); | 2143 VariableProxy* catch_var_defn = new(zone()) VariableProxy(catch_var); |
| 2137 result = new TryCatchStatement(try_block, catch_var_defn, catch_block); | 2144 result = |
| 2145 new(zone()) TryCatchStatement(try_block, catch_var_defn, catch_block); | |
| 2138 result->set_escaping_targets(collector.targets()); | 2146 result->set_escaping_targets(collector.targets()); |
| 2139 } else { | 2147 } else { |
| 2140 ASSERT(finally_block != NULL); | 2148 ASSERT(finally_block != NULL); |
| 2141 result = new TryFinallyStatement(try_block, finally_block); | 2149 result = new(zone()) TryFinallyStatement(try_block, finally_block); |
| 2142 // Add the jump targets of the try block and the catch block. | 2150 // Add the jump targets of the try block and the catch block. |
| 2143 for (int i = 0; i < collector.targets()->length(); i++) { | 2151 for (int i = 0; i < collector.targets()->length(); i++) { |
| 2144 catch_collector.AddTarget(collector.targets()->at(i)); | 2152 catch_collector.AddTarget(collector.targets()->at(i)); |
| 2145 } | 2153 } |
| 2146 result->set_escaping_targets(catch_collector.targets()); | 2154 result->set_escaping_targets(catch_collector.targets()); |
| 2147 } | 2155 } |
| 2148 | 2156 |
| 2149 return result; | 2157 return result; |
| 2150 } | 2158 } |
| 2151 | 2159 |
| 2152 | 2160 |
| 2153 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2161 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
| 2154 bool* ok) { | 2162 bool* ok) { |
| 2155 // DoStatement :: | 2163 // DoStatement :: |
| 2156 // 'do' Statement 'while' '(' Expression ')' ';' | 2164 // 'do' Statement 'while' '(' Expression ')' ';' |
| 2157 | 2165 |
| 2158 lexical_scope_->AddLoop(); | 2166 lexical_scope_->AddLoop(); |
| 2159 DoWhileStatement* loop = new DoWhileStatement(labels); | 2167 DoWhileStatement* loop = new(zone()) DoWhileStatement(labels); |
| 2160 Target target(&this->target_stack_, loop); | 2168 Target target(&this->target_stack_, loop); |
| 2161 | 2169 |
| 2162 Expect(Token::DO, CHECK_OK); | 2170 Expect(Token::DO, CHECK_OK); |
| 2163 Statement* body = ParseStatement(NULL, CHECK_OK); | 2171 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2164 Expect(Token::WHILE, CHECK_OK); | 2172 Expect(Token::WHILE, CHECK_OK); |
| 2165 Expect(Token::LPAREN, CHECK_OK); | 2173 Expect(Token::LPAREN, CHECK_OK); |
| 2166 | 2174 |
| 2167 if (loop != NULL) { | 2175 if (loop != NULL) { |
| 2168 int position = scanner().location().beg_pos; | 2176 int position = scanner().location().beg_pos; |
| 2169 loop->set_condition_position(position); | 2177 loop->set_condition_position(position); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2182 if (loop != NULL) loop->Initialize(cond, body); | 2190 if (loop != NULL) loop->Initialize(cond, body); |
| 2183 return loop; | 2191 return loop; |
| 2184 } | 2192 } |
| 2185 | 2193 |
| 2186 | 2194 |
| 2187 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2195 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
| 2188 // WhileStatement :: | 2196 // WhileStatement :: |
| 2189 // 'while' '(' Expression ')' Statement | 2197 // 'while' '(' Expression ')' Statement |
| 2190 | 2198 |
| 2191 lexical_scope_->AddLoop(); | 2199 lexical_scope_->AddLoop(); |
| 2192 WhileStatement* loop = new WhileStatement(labels); | 2200 WhileStatement* loop = new(zone()) WhileStatement(labels); |
| 2193 Target target(&this->target_stack_, loop); | 2201 Target target(&this->target_stack_, loop); |
| 2194 | 2202 |
| 2195 Expect(Token::WHILE, CHECK_OK); | 2203 Expect(Token::WHILE, CHECK_OK); |
| 2196 Expect(Token::LPAREN, CHECK_OK); | 2204 Expect(Token::LPAREN, CHECK_OK); |
| 2197 Expression* cond = ParseExpression(true, CHECK_OK); | 2205 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2198 if (cond != NULL) cond->set_is_loop_condition(true); | 2206 if (cond != NULL) cond->set_is_loop_condition(true); |
| 2199 Expect(Token::RPAREN, CHECK_OK); | 2207 Expect(Token::RPAREN, CHECK_OK); |
| 2200 Statement* body = ParseStatement(NULL, CHECK_OK); | 2208 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2201 | 2209 |
| 2202 if (loop != NULL) loop->Initialize(cond, body); | 2210 if (loop != NULL) loop->Initialize(cond, body); |
| 2203 return loop; | 2211 return loop; |
| 2204 } | 2212 } |
| 2205 | 2213 |
| 2206 | 2214 |
| 2207 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2215 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 2208 // ForStatement :: | 2216 // ForStatement :: |
| 2209 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2217 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2210 | 2218 |
| 2211 lexical_scope_->AddLoop(); | 2219 lexical_scope_->AddLoop(); |
| 2212 Statement* init = NULL; | 2220 Statement* init = NULL; |
| 2213 | 2221 |
| 2214 Expect(Token::FOR, CHECK_OK); | 2222 Expect(Token::FOR, CHECK_OK); |
| 2215 Expect(Token::LPAREN, CHECK_OK); | 2223 Expect(Token::LPAREN, CHECK_OK); |
| 2216 if (peek() != Token::SEMICOLON) { | 2224 if (peek() != Token::SEMICOLON) { |
| 2217 if (peek() == Token::VAR || peek() == Token::CONST) { | 2225 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2218 Expression* each = NULL; | 2226 Expression* each = NULL; |
| 2219 Block* variable_statement = | 2227 Block* variable_statement = |
| 2220 ParseVariableDeclarations(false, &each, CHECK_OK); | 2228 ParseVariableDeclarations(false, &each, CHECK_OK); |
| 2221 if (peek() == Token::IN && each != NULL) { | 2229 if (peek() == Token::IN && each != NULL) { |
| 2222 ForInStatement* loop = new ForInStatement(labels); | 2230 ForInStatement* loop = new(zone()) ForInStatement(labels); |
| 2223 Target target(&this->target_stack_, loop); | 2231 Target target(&this->target_stack_, loop); |
| 2224 | 2232 |
| 2225 Expect(Token::IN, CHECK_OK); | 2233 Expect(Token::IN, CHECK_OK); |
| 2226 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2234 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2227 Expect(Token::RPAREN, CHECK_OK); | 2235 Expect(Token::RPAREN, CHECK_OK); |
| 2228 | 2236 |
| 2229 Statement* body = ParseStatement(NULL, CHECK_OK); | 2237 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2230 loop->Initialize(each, enumerable, body); | 2238 loop->Initialize(each, enumerable, body); |
| 2231 Block* result = new Block(NULL, 2, false); | 2239 Block* result = new(zone()) Block(NULL, 2, false); |
| 2232 result->AddStatement(variable_statement); | 2240 result->AddStatement(variable_statement); |
| 2233 result->AddStatement(loop); | 2241 result->AddStatement(loop); |
| 2234 // Parsed for-in loop w/ variable/const declaration. | 2242 // Parsed for-in loop w/ variable/const declaration. |
| 2235 return result; | 2243 return result; |
| 2236 } else { | 2244 } else { |
| 2237 init = variable_statement; | 2245 init = variable_statement; |
| 2238 } | 2246 } |
| 2239 | 2247 |
| 2240 } else { | 2248 } else { |
| 2241 Expression* expression = ParseExpression(false, CHECK_OK); | 2249 Expression* expression = ParseExpression(false, CHECK_OK); |
| 2242 if (peek() == Token::IN) { | 2250 if (peek() == Token::IN) { |
| 2243 // Signal a reference error if the expression is an invalid | 2251 // Signal a reference error if the expression is an invalid |
| 2244 // left-hand side expression. We could report this as a syntax | 2252 // left-hand side expression. We could report this as a syntax |
| 2245 // error here but for compatibility with JSC we choose to report | 2253 // error here but for compatibility with JSC we choose to report |
| 2246 // the error at runtime. | 2254 // the error at runtime. |
| 2247 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2255 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2248 Handle<String> type = | 2256 Handle<String> type = |
| 2249 isolate()->factory()->invalid_lhs_in_for_in_symbol(); | 2257 isolate()->factory()->invalid_lhs_in_for_in_symbol(); |
| 2250 expression = NewThrowReferenceError(type); | 2258 expression = NewThrowReferenceError(type); |
| 2251 } | 2259 } |
| 2252 ForInStatement* loop = new ForInStatement(labels); | 2260 ForInStatement* loop = new(zone()) ForInStatement(labels); |
| 2253 Target target(&this->target_stack_, loop); | 2261 Target target(&this->target_stack_, loop); |
| 2254 | 2262 |
| 2255 Expect(Token::IN, CHECK_OK); | 2263 Expect(Token::IN, CHECK_OK); |
| 2256 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2264 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2257 Expect(Token::RPAREN, CHECK_OK); | 2265 Expect(Token::RPAREN, CHECK_OK); |
| 2258 | 2266 |
| 2259 Statement* body = ParseStatement(NULL, CHECK_OK); | 2267 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2260 if (loop) loop->Initialize(expression, enumerable, body); | 2268 if (loop) loop->Initialize(expression, enumerable, body); |
| 2261 // Parsed for-in loop. | 2269 // Parsed for-in loop. |
| 2262 return loop; | 2270 return loop; |
| 2263 | 2271 |
| 2264 } else { | 2272 } else { |
| 2265 init = new ExpressionStatement(expression); | 2273 init = new(zone()) ExpressionStatement(expression); |
| 2266 } | 2274 } |
| 2267 } | 2275 } |
| 2268 } | 2276 } |
| 2269 | 2277 |
| 2270 // Standard 'for' loop | 2278 // Standard 'for' loop |
| 2271 ForStatement* loop = new ForStatement(labels); | 2279 ForStatement* loop = new(zone()) ForStatement(labels); |
| 2272 Target target(&this->target_stack_, loop); | 2280 Target target(&this->target_stack_, loop); |
| 2273 | 2281 |
| 2274 // Parsed initializer at this point. | 2282 // Parsed initializer at this point. |
| 2275 Expect(Token::SEMICOLON, CHECK_OK); | 2283 Expect(Token::SEMICOLON, CHECK_OK); |
| 2276 | 2284 |
| 2277 Expression* cond = NULL; | 2285 Expression* cond = NULL; |
| 2278 if (peek() != Token::SEMICOLON) { | 2286 if (peek() != Token::SEMICOLON) { |
| 2279 cond = ParseExpression(true, CHECK_OK); | 2287 cond = ParseExpression(true, CHECK_OK); |
| 2280 if (cond != NULL) cond->set_is_loop_condition(true); | 2288 if (cond != NULL) cond->set_is_loop_condition(true); |
| 2281 } | 2289 } |
| 2282 Expect(Token::SEMICOLON, CHECK_OK); | 2290 Expect(Token::SEMICOLON, CHECK_OK); |
| 2283 | 2291 |
| 2284 Statement* next = NULL; | 2292 Statement* next = NULL; |
| 2285 if (peek() != Token::RPAREN) { | 2293 if (peek() != Token::RPAREN) { |
| 2286 Expression* exp = ParseExpression(true, CHECK_OK); | 2294 Expression* exp = ParseExpression(true, CHECK_OK); |
| 2287 next = new ExpressionStatement(exp); | 2295 next = new(zone()) ExpressionStatement(exp); |
| 2288 } | 2296 } |
| 2289 Expect(Token::RPAREN, CHECK_OK); | 2297 Expect(Token::RPAREN, CHECK_OK); |
| 2290 | 2298 |
| 2291 Statement* body = ParseStatement(NULL, CHECK_OK); | 2299 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2292 if (loop) loop->Initialize(init, cond, next, body); | 2300 if (loop) loop->Initialize(init, cond, next, body); |
| 2293 return loop; | 2301 return loop; |
| 2294 } | 2302 } |
| 2295 | 2303 |
| 2296 | 2304 |
| 2297 // Precedence = 1 | 2305 // Precedence = 1 |
| 2298 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { | 2306 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { |
| 2299 // Expression :: | 2307 // Expression :: |
| 2300 // AssignmentExpression | 2308 // AssignmentExpression |
| 2301 // Expression ',' AssignmentExpression | 2309 // Expression ',' AssignmentExpression |
| 2302 | 2310 |
| 2303 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2311 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2304 while (peek() == Token::COMMA) { | 2312 while (peek() == Token::COMMA) { |
| 2305 Expect(Token::COMMA, CHECK_OK); | 2313 Expect(Token::COMMA, CHECK_OK); |
| 2306 int position = scanner().location().beg_pos; | 2314 int position = scanner().location().beg_pos; |
| 2307 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2315 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2308 result = new BinaryOperation(Token::COMMA, result, right, position); | 2316 result = new(zone()) BinaryOperation(Token::COMMA, result, right, position); |
| 2309 } | 2317 } |
| 2310 return result; | 2318 return result; |
| 2311 } | 2319 } |
| 2312 | 2320 |
| 2313 | 2321 |
| 2314 // Precedence = 2 | 2322 // Precedence = 2 |
| 2315 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2323 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 2316 // AssignmentExpression :: | 2324 // AssignmentExpression :: |
| 2317 // ConditionalExpression | 2325 // ConditionalExpression |
| 2318 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2326 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2370 // expression. | 2378 // expression. |
| 2371 if ((op == Token::INIT_VAR | 2379 if ((op == Token::INIT_VAR |
| 2372 || op == Token::INIT_CONST | 2380 || op == Token::INIT_CONST |
| 2373 || op == Token::ASSIGN) | 2381 || op == Token::ASSIGN) |
| 2374 && (right->AsCall() == NULL)) { | 2382 && (right->AsCall() == NULL)) { |
| 2375 fni_->Infer(); | 2383 fni_->Infer(); |
| 2376 } | 2384 } |
| 2377 fni_->Leave(); | 2385 fni_->Leave(); |
| 2378 } | 2386 } |
| 2379 | 2387 |
| 2380 return new Assignment(op, expression, right, pos); | 2388 return new(zone()) Assignment(op, expression, right, pos); |
| 2381 } | 2389 } |
| 2382 | 2390 |
| 2383 | 2391 |
| 2384 // Precedence = 3 | 2392 // Precedence = 3 |
| 2385 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { | 2393 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
| 2386 // ConditionalExpression :: | 2394 // ConditionalExpression :: |
| 2387 // LogicalOrExpression | 2395 // LogicalOrExpression |
| 2388 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2396 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 2389 | 2397 |
| 2390 // We start using the binary expression parser for prec >= 4 only! | 2398 // We start using the binary expression parser for prec >= 4 only! |
| 2391 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 2399 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
| 2392 if (peek() != Token::CONDITIONAL) return expression; | 2400 if (peek() != Token::CONDITIONAL) return expression; |
| 2393 Consume(Token::CONDITIONAL); | 2401 Consume(Token::CONDITIONAL); |
| 2394 // In parsing the first assignment expression in conditional | 2402 // In parsing the first assignment expression in conditional |
| 2395 // expressions we always accept the 'in' keyword; see ECMA-262, | 2403 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 2396 // section 11.12, page 58. | 2404 // section 11.12, page 58. |
| 2397 int left_position = scanner().peek_location().beg_pos; | 2405 int left_position = scanner().peek_location().beg_pos; |
| 2398 Expression* left = ParseAssignmentExpression(true, CHECK_OK); | 2406 Expression* left = ParseAssignmentExpression(true, CHECK_OK); |
| 2399 Expect(Token::COLON, CHECK_OK); | 2407 Expect(Token::COLON, CHECK_OK); |
| 2400 int right_position = scanner().peek_location().beg_pos; | 2408 int right_position = scanner().peek_location().beg_pos; |
| 2401 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2409 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2402 return new Conditional(expression, left, right, | 2410 return new(zone()) Conditional(expression, left, right, |
| 2403 left_position, right_position); | 2411 left_position, right_position); |
| 2404 } | 2412 } |
| 2405 | 2413 |
| 2406 | 2414 |
| 2407 static int Precedence(Token::Value tok, bool accept_IN) { | 2415 static int Precedence(Token::Value tok, bool accept_IN) { |
| 2408 if (tok == Token::IN && !accept_IN) | 2416 if (tok == Token::IN && !accept_IN) |
| 2409 return 0; // 0 precedence will terminate binary expression parsing | 2417 return 0; // 0 precedence will terminate binary expression parsing |
| 2410 | 2418 |
| 2411 return Token::Precedence(tok); | 2419 return Token::Precedence(tok); |
| 2412 } | 2420 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2480 // We have a comparison. | 2488 // We have a comparison. |
| 2481 Token::Value cmp = op; | 2489 Token::Value cmp = op; |
| 2482 switch (op) { | 2490 switch (op) { |
| 2483 case Token::NE: cmp = Token::EQ; break; | 2491 case Token::NE: cmp = Token::EQ; break; |
| 2484 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; | 2492 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
| 2485 default: break; | 2493 default: break; |
| 2486 } | 2494 } |
| 2487 x = NewCompareNode(cmp, x, y, position); | 2495 x = NewCompareNode(cmp, x, y, position); |
| 2488 if (cmp != op) { | 2496 if (cmp != op) { |
| 2489 // The comparison was negated - add a NOT. | 2497 // The comparison was negated - add a NOT. |
| 2490 x = new UnaryOperation(Token::NOT, x); | 2498 x = new(zone()) UnaryOperation(Token::NOT, x); |
| 2491 } | 2499 } |
| 2492 | 2500 |
| 2493 } else { | 2501 } else { |
| 2494 // We have a "normal" binary operation. | 2502 // We have a "normal" binary operation. |
| 2495 x = new BinaryOperation(op, x, y, position); | 2503 x = new(zone()) BinaryOperation(op, x, y, position); |
| 2496 } | 2504 } |
| 2497 } | 2505 } |
| 2498 } | 2506 } |
| 2499 return x; | 2507 return x; |
| 2500 } | 2508 } |
| 2501 | 2509 |
| 2502 | 2510 |
| 2503 Expression* Parser::NewCompareNode(Token::Value op, | 2511 Expression* Parser::NewCompareNode(Token::Value op, |
| 2504 Expression* x, | 2512 Expression* x, |
| 2505 Expression* y, | 2513 Expression* y, |
| 2506 int position) { | 2514 int position) { |
| 2507 ASSERT(op != Token::NE && op != Token::NE_STRICT); | 2515 ASSERT(op != Token::NE && op != Token::NE_STRICT); |
| 2508 if (op == Token::EQ || op == Token::EQ_STRICT) { | 2516 if (op == Token::EQ || op == Token::EQ_STRICT) { |
| 2509 bool is_strict = (op == Token::EQ_STRICT); | 2517 bool is_strict = (op == Token::EQ_STRICT); |
| 2510 Literal* x_literal = x->AsLiteral(); | 2518 Literal* x_literal = x->AsLiteral(); |
| 2511 if (x_literal != NULL && x_literal->IsNull()) { | 2519 if (x_literal != NULL && x_literal->IsNull()) { |
| 2512 return new CompareToNull(is_strict, y); | 2520 return new(zone()) CompareToNull(is_strict, y); |
| 2513 } | 2521 } |
| 2514 | 2522 |
| 2515 Literal* y_literal = y->AsLiteral(); | 2523 Literal* y_literal = y->AsLiteral(); |
| 2516 if (y_literal != NULL && y_literal->IsNull()) { | 2524 if (y_literal != NULL && y_literal->IsNull()) { |
| 2517 return new CompareToNull(is_strict, x); | 2525 return new(zone()) CompareToNull(is_strict, x); |
| 2518 } | 2526 } |
| 2519 } | 2527 } |
| 2520 return new CompareOperation(op, x, y, position); | 2528 return new(zone()) CompareOperation(op, x, y, position); |
| 2521 } | 2529 } |
| 2522 | 2530 |
| 2523 | 2531 |
| 2524 Expression* Parser::ParseUnaryExpression(bool* ok) { | 2532 Expression* Parser::ParseUnaryExpression(bool* ok) { |
| 2525 // UnaryExpression :: | 2533 // UnaryExpression :: |
| 2526 // PostfixExpression | 2534 // PostfixExpression |
| 2527 // 'delete' UnaryExpression | 2535 // 'delete' UnaryExpression |
| 2528 // 'void' UnaryExpression | 2536 // 'void' UnaryExpression |
| 2529 // 'typeof' UnaryExpression | 2537 // 'typeof' UnaryExpression |
| 2530 // '++' UnaryExpression | 2538 // '++' UnaryExpression |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2557 // "delete identifier" is a syntax error in strict mode. | 2565 // "delete identifier" is a syntax error in strict mode. |
| 2558 if (op == Token::DELETE && top_scope_->is_strict_mode()) { | 2566 if (op == Token::DELETE && top_scope_->is_strict_mode()) { |
| 2559 VariableProxy* operand = expression->AsVariableProxy(); | 2567 VariableProxy* operand = expression->AsVariableProxy(); |
| 2560 if (operand != NULL && !operand->is_this()) { | 2568 if (operand != NULL && !operand->is_this()) { |
| 2561 ReportMessage("strict_delete", Vector<const char*>::empty()); | 2569 ReportMessage("strict_delete", Vector<const char*>::empty()); |
| 2562 *ok = false; | 2570 *ok = false; |
| 2563 return NULL; | 2571 return NULL; |
| 2564 } | 2572 } |
| 2565 } | 2573 } |
| 2566 | 2574 |
| 2567 return new UnaryOperation(op, expression); | 2575 return new(zone()) UnaryOperation(op, expression); |
| 2568 | 2576 |
| 2569 } else if (Token::IsCountOp(op)) { | 2577 } else if (Token::IsCountOp(op)) { |
| 2570 op = Next(); | 2578 op = Next(); |
| 2571 Expression* expression = ParseUnaryExpression(CHECK_OK); | 2579 Expression* expression = ParseUnaryExpression(CHECK_OK); |
| 2572 // Signal a reference error if the expression is an invalid | 2580 // Signal a reference error if the expression is an invalid |
| 2573 // left-hand side expression. We could report this as a syntax | 2581 // left-hand side expression. We could report this as a syntax |
| 2574 // error here but for compatibility with JSC we choose to report the | 2582 // error here but for compatibility with JSC we choose to report the |
| 2575 // error at runtime. | 2583 // error at runtime. |
| 2576 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2584 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2577 Handle<String> type = | 2585 Handle<String> type = |
| 2578 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); | 2586 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); |
| 2579 expression = NewThrowReferenceError(type); | 2587 expression = NewThrowReferenceError(type); |
| 2580 } | 2588 } |
| 2581 | 2589 |
| 2582 if (top_scope_->is_strict_mode()) { | 2590 if (top_scope_->is_strict_mode()) { |
| 2583 // Prefix expression operand in strict mode may not be eval or arguments. | 2591 // Prefix expression operand in strict mode may not be eval or arguments. |
| 2584 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 2592 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2585 } | 2593 } |
| 2586 | 2594 |
| 2587 int position = scanner().location().beg_pos; | 2595 int position = scanner().location().beg_pos; |
| 2588 IncrementOperation* increment = new IncrementOperation(op, expression); | 2596 IncrementOperation* increment = |
| 2589 return new CountOperation(true /* prefix */, increment, position); | 2597 new(zone()) IncrementOperation(op, expression); |
| 2598 return new(zone()) CountOperation(true /* prefix */, increment, position); | |
| 2590 | 2599 |
| 2591 } else { | 2600 } else { |
| 2592 return ParsePostfixExpression(ok); | 2601 return ParsePostfixExpression(ok); |
| 2593 } | 2602 } |
| 2594 } | 2603 } |
| 2595 | 2604 |
| 2596 | 2605 |
| 2597 Expression* Parser::ParsePostfixExpression(bool* ok) { | 2606 Expression* Parser::ParsePostfixExpression(bool* ok) { |
| 2598 // PostfixExpression :: | 2607 // PostfixExpression :: |
| 2599 // LeftHandSideExpression ('++' | '--')? | 2608 // LeftHandSideExpression ('++' | '--')? |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2611 expression = NewThrowReferenceError(type); | 2620 expression = NewThrowReferenceError(type); |
| 2612 } | 2621 } |
| 2613 | 2622 |
| 2614 if (top_scope_->is_strict_mode()) { | 2623 if (top_scope_->is_strict_mode()) { |
| 2615 // Postfix expression operand in strict mode may not be eval or arguments. | 2624 // Postfix expression operand in strict mode may not be eval or arguments. |
| 2616 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 2625 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2617 } | 2626 } |
| 2618 | 2627 |
| 2619 Token::Value next = Next(); | 2628 Token::Value next = Next(); |
| 2620 int position = scanner().location().beg_pos; | 2629 int position = scanner().location().beg_pos; |
| 2621 IncrementOperation* increment = new IncrementOperation(next, expression); | 2630 IncrementOperation* increment = |
| 2622 expression = new CountOperation(false /* postfix */, increment, position); | 2631 new(zone()) IncrementOperation(next, expression); |
| 2632 expression = | |
| 2633 new(zone()) CountOperation(false /* postfix */, increment, position); | |
| 2623 } | 2634 } |
| 2624 return expression; | 2635 return expression; |
| 2625 } | 2636 } |
| 2626 | 2637 |
| 2627 | 2638 |
| 2628 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { | 2639 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
| 2629 // LeftHandSideExpression :: | 2640 // LeftHandSideExpression :: |
| 2630 // (NewExpression | MemberExpression) ... | 2641 // (NewExpression | MemberExpression) ... |
| 2631 | 2642 |
| 2632 Expression* result; | 2643 Expression* result; |
| 2633 if (peek() == Token::NEW) { | 2644 if (peek() == Token::NEW) { |
| 2634 result = ParseNewExpression(CHECK_OK); | 2645 result = ParseNewExpression(CHECK_OK); |
| 2635 } else { | 2646 } else { |
| 2636 result = ParseMemberExpression(CHECK_OK); | 2647 result = ParseMemberExpression(CHECK_OK); |
| 2637 } | 2648 } |
| 2638 | 2649 |
| 2639 while (true) { | 2650 while (true) { |
| 2640 switch (peek()) { | 2651 switch (peek()) { |
| 2641 case Token::LBRACK: { | 2652 case Token::LBRACK: { |
| 2642 Consume(Token::LBRACK); | 2653 Consume(Token::LBRACK); |
| 2643 int pos = scanner().location().beg_pos; | 2654 int pos = scanner().location().beg_pos; |
| 2644 Expression* index = ParseExpression(true, CHECK_OK); | 2655 Expression* index = ParseExpression(true, CHECK_OK); |
| 2645 result = new Property(result, index, pos); | 2656 result = new(zone()) Property(result, index, pos); |
| 2646 Expect(Token::RBRACK, CHECK_OK); | 2657 Expect(Token::RBRACK, CHECK_OK); |
| 2647 break; | 2658 break; |
| 2648 } | 2659 } |
| 2649 | 2660 |
| 2650 case Token::LPAREN: { | 2661 case Token::LPAREN: { |
| 2651 int pos = scanner().location().beg_pos; | 2662 int pos = scanner().location().beg_pos; |
| 2652 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 2663 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 2653 | 2664 |
| 2654 // Keep track of eval() calls since they disable all local variable | 2665 // Keep track of eval() calls since they disable all local variable |
| 2655 // optimizations. | 2666 // optimizations. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 2673 } | 2684 } |
| 2674 } | 2685 } |
| 2675 result = NewCall(result, args, pos); | 2686 result = NewCall(result, args, pos); |
| 2676 break; | 2687 break; |
| 2677 } | 2688 } |
| 2678 | 2689 |
| 2679 case Token::PERIOD: { | 2690 case Token::PERIOD: { |
| 2680 Consume(Token::PERIOD); | 2691 Consume(Token::PERIOD); |
| 2681 int pos = scanner().location().beg_pos; | 2692 int pos = scanner().location().beg_pos; |
| 2682 Handle<String> name = ParseIdentifierName(CHECK_OK); | 2693 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 2683 result = new Property(result, new Literal(name), pos); | 2694 result = new(zone()) Property(result, new(zone()) Literal(name), pos); |
| 2684 if (fni_ != NULL) fni_->PushLiteralName(name); | 2695 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 2685 break; | 2696 break; |
| 2686 } | 2697 } |
| 2687 | 2698 |
| 2688 default: | 2699 default: |
| 2689 return result; | 2700 return result; |
| 2690 } | 2701 } |
| 2691 } | 2702 } |
| 2692 } | 2703 } |
| 2693 | 2704 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2709 | 2720 |
| 2710 Expression* result; | 2721 Expression* result; |
| 2711 if (peek() == Token::NEW) { | 2722 if (peek() == Token::NEW) { |
| 2712 result = ParseNewPrefix(stack, CHECK_OK); | 2723 result = ParseNewPrefix(stack, CHECK_OK); |
| 2713 } else { | 2724 } else { |
| 2714 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); | 2725 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); |
| 2715 } | 2726 } |
| 2716 | 2727 |
| 2717 if (!stack->is_empty()) { | 2728 if (!stack->is_empty()) { |
| 2718 int last = stack->pop(); | 2729 int last = stack->pop(); |
| 2719 result = new CallNew(result, new ZoneList<Expression*>(0), last); | 2730 result = new(zone()) CallNew(result, new ZoneList<Expression*>(0), last); |
| 2720 } | 2731 } |
| 2721 return result; | 2732 return result; |
| 2722 } | 2733 } |
| 2723 | 2734 |
| 2724 | 2735 |
| 2725 Expression* Parser::ParseNewExpression(bool* ok) { | 2736 Expression* Parser::ParseNewExpression(bool* ok) { |
| 2726 PositionStack stack(ok); | 2737 PositionStack stack(ok); |
| 2727 return ParseNewPrefix(&stack, ok); | 2738 return ParseNewPrefix(&stack, ok); |
| 2728 } | 2739 } |
| 2729 | 2740 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 2754 } else { | 2765 } else { |
| 2755 result = ParsePrimaryExpression(CHECK_OK); | 2766 result = ParsePrimaryExpression(CHECK_OK); |
| 2756 } | 2767 } |
| 2757 | 2768 |
| 2758 while (true) { | 2769 while (true) { |
| 2759 switch (peek()) { | 2770 switch (peek()) { |
| 2760 case Token::LBRACK: { | 2771 case Token::LBRACK: { |
| 2761 Consume(Token::LBRACK); | 2772 Consume(Token::LBRACK); |
| 2762 int pos = scanner().location().beg_pos; | 2773 int pos = scanner().location().beg_pos; |
| 2763 Expression* index = ParseExpression(true, CHECK_OK); | 2774 Expression* index = ParseExpression(true, CHECK_OK); |
| 2764 result = new Property(result, index, pos); | 2775 result = new(zone()) Property(result, index, pos); |
| 2765 Expect(Token::RBRACK, CHECK_OK); | 2776 Expect(Token::RBRACK, CHECK_OK); |
| 2766 break; | 2777 break; |
| 2767 } | 2778 } |
| 2768 case Token::PERIOD: { | 2779 case Token::PERIOD: { |
| 2769 Consume(Token::PERIOD); | 2780 Consume(Token::PERIOD); |
| 2770 int pos = scanner().location().beg_pos; | 2781 int pos = scanner().location().beg_pos; |
| 2771 Handle<String> name = ParseIdentifierName(CHECK_OK); | 2782 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 2772 result = new Property(result, new Literal(name), pos); | 2783 result = new(zone()) Property(result, new(zone()) Literal(name), pos); |
| 2773 if (fni_ != NULL) fni_->PushLiteralName(name); | 2784 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 2774 break; | 2785 break; |
| 2775 } | 2786 } |
| 2776 case Token::LPAREN: { | 2787 case Token::LPAREN: { |
| 2777 if ((stack == NULL) || stack->is_empty()) return result; | 2788 if ((stack == NULL) || stack->is_empty()) return result; |
| 2778 // Consume one of the new prefixes (already parsed). | 2789 // Consume one of the new prefixes (already parsed). |
| 2779 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 2790 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 2780 int last = stack->pop(); | 2791 int last = stack->pop(); |
| 2781 result = new CallNew(result, args, last); | 2792 result = new CallNew(result, args, last); |
| 2782 break; | 2793 break; |
| 2783 } | 2794 } |
| 2784 default: | 2795 default: |
| 2785 return result; | 2796 return result; |
| 2786 } | 2797 } |
| 2787 } | 2798 } |
| 2788 } | 2799 } |
| 2789 | 2800 |
| 2790 | 2801 |
| 2791 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { | 2802 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
| 2792 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 2803 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
| 2793 // contexts this is used as a statement which invokes the debugger as i a | 2804 // contexts this is used as a statement which invokes the debugger as i a |
| 2794 // break point is present. | 2805 // break point is present. |
| 2795 // DebuggerStatement :: | 2806 // DebuggerStatement :: |
| 2796 // 'debugger' ';' | 2807 // 'debugger' ';' |
| 2797 | 2808 |
| 2798 Expect(Token::DEBUGGER, CHECK_OK); | 2809 Expect(Token::DEBUGGER, CHECK_OK); |
| 2799 ExpectSemicolon(CHECK_OK); | 2810 ExpectSemicolon(CHECK_OK); |
| 2800 return new DebuggerStatement(); | 2811 return new(zone()) DebuggerStatement(); |
| 2801 } | 2812 } |
| 2802 | 2813 |
| 2803 | 2814 |
| 2804 void Parser::ReportUnexpectedToken(Token::Value token) { | 2815 void Parser::ReportUnexpectedToken(Token::Value token) { |
| 2805 // We don't report stack overflows here, to avoid increasing the | 2816 // We don't report stack overflows here, to avoid increasing the |
| 2806 // stack depth even further. Instead we report it after parsing is | 2817 // stack depth even further. Instead we report it after parsing is |
| 2807 // over, in ParseProgram/ParseJson. | 2818 // over, in ParseProgram/ParseJson. |
| 2808 if (token == Token::ILLEGAL && stack_overflow_) return; | 2819 if (token == Token::ILLEGAL && stack_overflow_) return; |
| 2809 // Four of the tokens are treated specially | 2820 // Four of the tokens are treated specially |
| 2810 switch (token) { | 2821 switch (token) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2859 switch (peek()) { | 2870 switch (peek()) { |
| 2860 case Token::THIS: { | 2871 case Token::THIS: { |
| 2861 Consume(Token::THIS); | 2872 Consume(Token::THIS); |
| 2862 VariableProxy* recv = top_scope_->receiver(); | 2873 VariableProxy* recv = top_scope_->receiver(); |
| 2863 result = recv; | 2874 result = recv; |
| 2864 break; | 2875 break; |
| 2865 } | 2876 } |
| 2866 | 2877 |
| 2867 case Token::NULL_LITERAL: | 2878 case Token::NULL_LITERAL: |
| 2868 Consume(Token::NULL_LITERAL); | 2879 Consume(Token::NULL_LITERAL); |
| 2869 result = new Literal(isolate()->factory()->null_value()); | 2880 result = new(zone()) Literal(isolate()->factory()->null_value()); |
| 2870 break; | 2881 break; |
| 2871 | 2882 |
| 2872 case Token::TRUE_LITERAL: | 2883 case Token::TRUE_LITERAL: |
| 2873 Consume(Token::TRUE_LITERAL); | 2884 Consume(Token::TRUE_LITERAL); |
| 2874 result = new Literal(isolate()->factory()->true_value()); | 2885 result = new(zone()) Literal(isolate()->factory()->true_value()); |
| 2875 break; | 2886 break; |
| 2876 | 2887 |
| 2877 case Token::FALSE_LITERAL: | 2888 case Token::FALSE_LITERAL: |
| 2878 Consume(Token::FALSE_LITERAL); | 2889 Consume(Token::FALSE_LITERAL); |
| 2879 result = new Literal(isolate()->factory()->false_value()); | 2890 result = new(zone()) Literal(isolate()->factory()->false_value()); |
| 2880 break; | 2891 break; |
| 2881 | 2892 |
| 2882 case Token::IDENTIFIER: | 2893 case Token::IDENTIFIER: |
| 2883 case Token::FUTURE_RESERVED_WORD: { | 2894 case Token::FUTURE_RESERVED_WORD: { |
| 2884 Handle<String> name = ParseIdentifier(CHECK_OK); | 2895 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2885 if (fni_ != NULL) fni_->PushVariableName(name); | 2896 if (fni_ != NULL) fni_->PushVariableName(name); |
| 2886 result = top_scope_->NewUnresolved(name, | 2897 result = top_scope_->NewUnresolved(name, |
| 2887 inside_with(), | 2898 inside_with(), |
| 2888 scanner().location().beg_pos); | 2899 scanner().location().beg_pos); |
| 2889 break; | 2900 break; |
| 2890 } | 2901 } |
| 2891 | 2902 |
| 2892 case Token::NUMBER: { | 2903 case Token::NUMBER: { |
| 2893 Consume(Token::NUMBER); | 2904 Consume(Token::NUMBER); |
| 2894 ASSERT(scanner().is_literal_ascii()); | 2905 ASSERT(scanner().is_literal_ascii()); |
| 2895 double value = StringToDouble(scanner().literal_ascii_string(), | 2906 double value = StringToDouble(scanner().literal_ascii_string(), |
| 2896 ALLOW_HEX | ALLOW_OCTALS); | 2907 ALLOW_HEX | ALLOW_OCTALS); |
| 2897 result = NewNumberLiteral(value); | 2908 result = NewNumberLiteral(value); |
| 2898 break; | 2909 break; |
| 2899 } | 2910 } |
| 2900 | 2911 |
| 2901 case Token::STRING: { | 2912 case Token::STRING: { |
| 2902 Consume(Token::STRING); | 2913 Consume(Token::STRING); |
| 2903 Handle<String> symbol = GetSymbol(CHECK_OK); | 2914 Handle<String> symbol = GetSymbol(CHECK_OK); |
| 2904 result = new Literal(symbol); | 2915 result = new(zone()) Literal(symbol); |
| 2905 if (fni_ != NULL) fni_->PushLiteralName(symbol); | 2916 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
| 2906 break; | 2917 break; |
| 2907 } | 2918 } |
| 2908 | 2919 |
| 2909 case Token::ASSIGN_DIV: | 2920 case Token::ASSIGN_DIV: |
| 2910 result = ParseRegExpLiteral(true, CHECK_OK); | 2921 result = ParseRegExpLiteral(true, CHECK_OK); |
| 2911 break; | 2922 break; |
| 2912 | 2923 |
| 2913 case Token::DIV: | 2924 case Token::DIV: |
| 2914 result = ParseRegExpLiteral(false, CHECK_OK); | 2925 result = ParseRegExpLiteral(false, CHECK_OK); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3021 literals->set(i, *boilerplate_value); | 3032 literals->set(i, *boilerplate_value); |
| 3022 } | 3033 } |
| 3023 } | 3034 } |
| 3024 | 3035 |
| 3025 // Simple and shallow arrays can be lazily copied, we transform the | 3036 // Simple and shallow arrays can be lazily copied, we transform the |
| 3026 // elements array to a copy-on-write array. | 3037 // elements array to a copy-on-write array. |
| 3027 if (is_simple && depth == 1 && values->length() > 0) { | 3038 if (is_simple && depth == 1 && values->length() > 0) { |
| 3028 literals->set_map(isolate()->heap()->fixed_cow_array_map()); | 3039 literals->set_map(isolate()->heap()->fixed_cow_array_map()); |
| 3029 } | 3040 } |
| 3030 | 3041 |
| 3031 return new ArrayLiteral(literals, values, | 3042 return new(zone()) ArrayLiteral(literals, values, |
| 3032 literal_index, is_simple, depth); | 3043 literal_index, is_simple, depth); |
| 3033 } | 3044 } |
| 3034 | 3045 |
| 3035 | 3046 |
| 3036 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { | 3047 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { |
| 3037 return property != NULL && | 3048 return property != NULL && |
| 3038 property->kind() != ObjectLiteral::Property::PROTOTYPE; | 3049 property->kind() != ObjectLiteral::Property::PROTOTYPE; |
| 3039 } | 3050 } |
| 3040 | 3051 |
| 3041 | 3052 |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3299 } | 3310 } |
| 3300 FunctionLiteral* value = | 3311 FunctionLiteral* value = |
| 3301 ParseFunctionLiteral(name, | 3312 ParseFunctionLiteral(name, |
| 3302 false, // reserved words are allowed here | 3313 false, // reserved words are allowed here |
| 3303 RelocInfo::kNoPosition, | 3314 RelocInfo::kNoPosition, |
| 3304 DECLARATION, | 3315 DECLARATION, |
| 3305 CHECK_OK); | 3316 CHECK_OK); |
| 3306 // Allow any number of parameters for compatiabilty with JSC. | 3317 // Allow any number of parameters for compatiabilty with JSC. |
| 3307 // Specification only allows zero parameters for get and one for set. | 3318 // Specification only allows zero parameters for get and one for set. |
| 3308 ObjectLiteral::Property* property = | 3319 ObjectLiteral::Property* property = |
| 3309 new ObjectLiteral::Property(is_getter, value); | 3320 new(zone()) ObjectLiteral::Property(is_getter, value); |
| 3310 return property; | 3321 return property; |
| 3311 } else { | 3322 } else { |
| 3312 ReportUnexpectedToken(next); | 3323 ReportUnexpectedToken(next); |
| 3313 *ok = false; | 3324 *ok = false; |
| 3314 return NULL; | 3325 return NULL; |
| 3315 } | 3326 } |
| 3316 } | 3327 } |
| 3317 | 3328 |
| 3318 | 3329 |
| 3319 Expression* Parser::ParseObjectLiteral(bool* ok) { | 3330 Expression* Parser::ParseObjectLiteral(bool* ok) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3365 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3376 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 3366 | 3377 |
| 3367 if (fni_ != NULL) { | 3378 if (fni_ != NULL) { |
| 3368 fni_->Infer(); | 3379 fni_->Infer(); |
| 3369 fni_->Leave(); | 3380 fni_->Leave(); |
| 3370 } | 3381 } |
| 3371 continue; // restart the while | 3382 continue; // restart the while |
| 3372 } | 3383 } |
| 3373 // Failed to parse as get/set property, so it's just a property | 3384 // Failed to parse as get/set property, so it's just a property |
| 3374 // called "get" or "set". | 3385 // called "get" or "set". |
| 3375 key = new Literal(id); | 3386 key = new(zone()) Literal(id); |
| 3376 break; | 3387 break; |
| 3377 } | 3388 } |
| 3378 case Token::STRING: { | 3389 case Token::STRING: { |
| 3379 Consume(Token::STRING); | 3390 Consume(Token::STRING); |
| 3380 Handle<String> string = GetSymbol(CHECK_OK); | 3391 Handle<String> string = GetSymbol(CHECK_OK); |
| 3381 if (fni_ != NULL) fni_->PushLiteralName(string); | 3392 if (fni_ != NULL) fni_->PushLiteralName(string); |
| 3382 uint32_t index; | 3393 uint32_t index; |
| 3383 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3394 if (!string.is_null() && string->AsArrayIndex(&index)) { |
| 3384 key = NewNumberLiteral(index); | 3395 key = NewNumberLiteral(index); |
| 3385 break; | 3396 break; |
| 3386 } | 3397 } |
| 3387 key = new Literal(string); | 3398 key = new(zone()) Literal(string); |
| 3388 break; | 3399 break; |
| 3389 } | 3400 } |
| 3390 case Token::NUMBER: { | 3401 case Token::NUMBER: { |
| 3391 Consume(Token::NUMBER); | 3402 Consume(Token::NUMBER); |
| 3392 ASSERT(scanner().is_literal_ascii()); | 3403 ASSERT(scanner().is_literal_ascii()); |
| 3393 double value = StringToDouble(scanner().literal_ascii_string(), | 3404 double value = StringToDouble(scanner().literal_ascii_string(), |
| 3394 ALLOW_HEX | ALLOW_OCTALS); | 3405 ALLOW_HEX | ALLOW_OCTALS); |
| 3395 key = NewNumberLiteral(value); | 3406 key = NewNumberLiteral(value); |
| 3396 break; | 3407 break; |
| 3397 } | 3408 } |
| 3398 default: | 3409 default: |
| 3399 if (Token::IsKeyword(next)) { | 3410 if (Token::IsKeyword(next)) { |
| 3400 Consume(next); | 3411 Consume(next); |
| 3401 Handle<String> string = GetSymbol(CHECK_OK); | 3412 Handle<String> string = GetSymbol(CHECK_OK); |
| 3402 key = new Literal(string); | 3413 key = new(zone()) Literal(string); |
| 3403 } else { | 3414 } else { |
| 3404 // Unexpected token. | 3415 // Unexpected token. |
| 3405 Token::Value next = Next(); | 3416 Token::Value next = Next(); |
| 3406 ReportUnexpectedToken(next); | 3417 ReportUnexpectedToken(next); |
| 3407 *ok = false; | 3418 *ok = false; |
| 3408 return NULL; | 3419 return NULL; |
| 3409 } | 3420 } |
| 3410 } | 3421 } |
| 3411 | 3422 |
| 3412 Expect(Token::COLON, CHECK_OK); | 3423 Expect(Token::COLON, CHECK_OK); |
| 3413 Expression* value = ParseAssignmentExpression(true, CHECK_OK); | 3424 Expression* value = ParseAssignmentExpression(true, CHECK_OK); |
| 3414 | 3425 |
| 3415 ObjectLiteral::Property* property = | 3426 ObjectLiteral::Property* property = |
| 3416 new ObjectLiteral::Property(key, value); | 3427 new(zone()) ObjectLiteral::Property(key, value); |
| 3417 | 3428 |
| 3418 // Mark object literals that contain function literals and pretenure the | 3429 // Mark object literals that contain function literals and pretenure the |
| 3419 // literal so it can be added as a constant function property. | 3430 // literal so it can be added as a constant function property. |
| 3420 if (value->AsFunctionLiteral() != NULL) { | 3431 if (value->AsFunctionLiteral() != NULL) { |
| 3421 has_function = true; | 3432 has_function = true; |
| 3422 value->AsFunctionLiteral()->set_pretenure(true); | 3433 value->AsFunctionLiteral()->set_pretenure(true); |
| 3423 } | 3434 } |
| 3424 | 3435 |
| 3425 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 3436 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
| 3426 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; | 3437 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 3445 number_of_boilerplate_properties * 2, TENURED); | 3456 number_of_boilerplate_properties * 2, TENURED); |
| 3446 | 3457 |
| 3447 bool is_simple = true; | 3458 bool is_simple = true; |
| 3448 bool fast_elements = true; | 3459 bool fast_elements = true; |
| 3449 int depth = 1; | 3460 int depth = 1; |
| 3450 BuildObjectLiteralConstantProperties(properties, | 3461 BuildObjectLiteralConstantProperties(properties, |
| 3451 constant_properties, | 3462 constant_properties, |
| 3452 &is_simple, | 3463 &is_simple, |
| 3453 &fast_elements, | 3464 &fast_elements, |
| 3454 &depth); | 3465 &depth); |
| 3455 return new ObjectLiteral(constant_properties, | 3466 return new(zone()) ObjectLiteral(constant_properties, |
| 3456 properties, | 3467 properties, |
| 3457 literal_index, | 3468 literal_index, |
| 3458 is_simple, | 3469 is_simple, |
| 3459 fast_elements, | 3470 fast_elements, |
| 3460 depth, | 3471 depth, |
| 3461 has_function); | 3472 has_function); |
| 3462 } | 3473 } |
| 3463 | 3474 |
| 3464 | 3475 |
| 3465 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | 3476 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
| 3466 if (!scanner().ScanRegExpPattern(seen_equal)) { | 3477 if (!scanner().ScanRegExpPattern(seen_equal)) { |
| 3467 Next(); | 3478 Next(); |
| 3468 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | 3479 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
| 3469 *ok = false; | 3480 *ok = false; |
| 3470 return NULL; | 3481 return NULL; |
| 3471 } | 3482 } |
| 3472 | 3483 |
| 3473 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); | 3484 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); |
| 3474 | 3485 |
| 3475 Handle<String> js_pattern = NextLiteralString(TENURED); | 3486 Handle<String> js_pattern = NextLiteralString(TENURED); |
| 3476 scanner().ScanRegExpFlags(); | 3487 scanner().ScanRegExpFlags(); |
| 3477 Handle<String> js_flags = NextLiteralString(TENURED); | 3488 Handle<String> js_flags = NextLiteralString(TENURED); |
| 3478 Next(); | 3489 Next(); |
| 3479 | 3490 |
| 3480 return new RegExpLiteral(js_pattern, js_flags, literal_index); | 3491 return new(zone()) RegExpLiteral(js_pattern, js_flags, literal_index); |
| 3481 } | 3492 } |
| 3482 | 3493 |
| 3483 | 3494 |
| 3484 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 3495 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
| 3485 // Arguments :: | 3496 // Arguments :: |
| 3486 // '(' (AssignmentExpression)*[','] ')' | 3497 // '(' (AssignmentExpression)*[','] ')' |
| 3487 | 3498 |
| 3488 ZoneList<Expression*>* result = new ZoneList<Expression*>(4); | 3499 ZoneList<Expression*>* result = new ZoneList<Expression*>(4); |
| 3489 Expect(Token::LPAREN, CHECK_OK); | 3500 Expect(Token::LPAREN, CHECK_OK); |
| 3490 bool done = (peek() == Token::RPAREN); | 3501 bool done = (peek() == Token::RPAREN); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3573 // declaration to the body of the function with the name of the | 3584 // declaration to the body of the function with the name of the |
| 3574 // function and let it refer to the function itself (closure). | 3585 // function and let it refer to the function itself (closure). |
| 3575 // NOTE: We create a proxy and resolve it here so that in the | 3586 // NOTE: We create a proxy and resolve it here so that in the |
| 3576 // future we can change the AST to only refer to VariableProxies | 3587 // future we can change the AST to only refer to VariableProxies |
| 3577 // instead of Variables and Proxis as is the case now. | 3588 // instead of Variables and Proxis as is the case now. |
| 3578 if (!function_name.is_null() && function_name->length() > 0) { | 3589 if (!function_name.is_null() && function_name->length() > 0) { |
| 3579 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); | 3590 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); |
| 3580 VariableProxy* fproxy = | 3591 VariableProxy* fproxy = |
| 3581 top_scope_->NewUnresolved(function_name, inside_with()); | 3592 top_scope_->NewUnresolved(function_name, inside_with()); |
| 3582 fproxy->BindTo(fvar); | 3593 fproxy->BindTo(fvar); |
| 3583 body->Add(new ExpressionStatement( | 3594 body->Add(new(zone()) ExpressionStatement( |
| 3584 new Assignment(Token::INIT_CONST, fproxy, | 3595 new(zone()) Assignment(Token::INIT_CONST, fproxy, |
| 3585 new ThisFunction(), | 3596 new(zone()) ThisFunction(), |
| 3586 RelocInfo::kNoPosition))); | 3597 RelocInfo::kNoPosition))); |
| 3587 } | 3598 } |
| 3588 | 3599 |
| 3589 // Determine if the function will be lazily compiled. The mode can | 3600 // Determine if the function will be lazily compiled. The mode can |
| 3590 // only be PARSE_LAZILY if the --lazy flag is true. | 3601 // only be PARSE_LAZILY if the --lazy flag is true. |
| 3591 bool is_lazily_compiled = (mode() == PARSE_LAZILY && | 3602 bool is_lazily_compiled = (mode() == PARSE_LAZILY && |
| 3592 top_scope_->outer_scope()->is_global_scope() && | 3603 top_scope_->outer_scope()->is_global_scope() && |
| 3593 top_scope_->HasTrivialOuterContext() && | 3604 top_scope_->HasTrivialOuterContext() && |
| 3594 !parenthesized_function_); | 3605 !parenthesized_function_); |
| 3595 parenthesized_function_ = false; // The bit was set for this function only. | 3606 parenthesized_function_ = false; // The bit was set for this function only. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3669 if (reserved_loc.IsValid()) { | 3680 if (reserved_loc.IsValid()) { |
| 3670 ReportMessageAt(reserved_loc, "strict_reserved_word", | 3681 ReportMessageAt(reserved_loc, "strict_reserved_word", |
| 3671 Vector<const char*>::empty()); | 3682 Vector<const char*>::empty()); |
| 3672 *ok = false; | 3683 *ok = false; |
| 3673 return NULL; | 3684 return NULL; |
| 3674 } | 3685 } |
| 3675 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); | 3686 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); |
| 3676 } | 3687 } |
| 3677 | 3688 |
| 3678 FunctionLiteral* function_literal = | 3689 FunctionLiteral* function_literal = |
| 3679 new FunctionLiteral(name, | 3690 new(zone()) FunctionLiteral(name, |
| 3680 top_scope_, | 3691 top_scope_, |
| 3681 body, | 3692 body, |
| 3682 materialized_literal_count, | 3693 materialized_literal_count, |
| 3683 expected_property_count, | 3694 expected_property_count, |
| 3684 only_simple_this_property_assignments, | 3695 only_simple_this_property_assignments, |
| 3685 this_property_assignments, | 3696 this_property_assignments, |
| 3686 num_parameters, | 3697 num_parameters, |
| 3687 start_pos, | 3698 start_pos, |
| 3688 end_pos, | 3699 end_pos, |
| 3689 function_name->length() > 0, | 3700 function_name->length() > 0, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3731 // Check that the expected number of arguments are being passed. | 3742 // Check that the expected number of arguments are being passed. |
| 3732 if (function != NULL && | 3743 if (function != NULL && |
| 3733 function->nargs != -1 && | 3744 function->nargs != -1 && |
| 3734 function->nargs != args->length()) { | 3745 function->nargs != args->length()) { |
| 3735 ReportMessage("illegal_access", Vector<const char*>::empty()); | 3746 ReportMessage("illegal_access", Vector<const char*>::empty()); |
| 3736 *ok = false; | 3747 *ok = false; |
| 3737 return NULL; | 3748 return NULL; |
| 3738 } | 3749 } |
| 3739 | 3750 |
| 3740 // We have a valid intrinsics call or a call to a builtin. | 3751 // We have a valid intrinsics call or a call to a builtin. |
| 3741 return new CallRuntime(name, function, args); | 3752 return new(zone()) CallRuntime(name, function, args); |
| 3742 } | 3753 } |
| 3743 | 3754 |
| 3744 | 3755 |
| 3745 bool Parser::peek_any_identifier() { | 3756 bool Parser::peek_any_identifier() { |
| 3746 Token::Value next = peek(); | 3757 Token::Value next = peek(); |
| 3747 return next == Token::IDENTIFIER || | 3758 return next == Token::IDENTIFIER || |
| 3748 next == Token::FUTURE_RESERVED_WORD; | 3759 next == Token::FUTURE_RESERVED_WORD; |
| 3749 } | 3760 } |
| 3750 | 3761 |
| 3751 | 3762 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3786 if (scanner().has_line_terminator_before_next() || | 3797 if (scanner().has_line_terminator_before_next() || |
| 3787 tok == Token::RBRACE || | 3798 tok == Token::RBRACE || |
| 3788 tok == Token::EOS) { | 3799 tok == Token::EOS) { |
| 3789 return; | 3800 return; |
| 3790 } | 3801 } |
| 3791 Expect(Token::SEMICOLON, ok); | 3802 Expect(Token::SEMICOLON, ok); |
| 3792 } | 3803 } |
| 3793 | 3804 |
| 3794 | 3805 |
| 3795 Literal* Parser::GetLiteralUndefined() { | 3806 Literal* Parser::GetLiteralUndefined() { |
| 3796 return new Literal(isolate()->factory()->undefined_value()); | 3807 return new(zone()) Literal(isolate()->factory()->undefined_value()); |
| 3797 } | 3808 } |
| 3798 | 3809 |
| 3799 | 3810 |
| 3800 Literal* Parser::GetLiteralTheHole() { | 3811 Literal* Parser::GetLiteralTheHole() { |
| 3801 return new Literal(isolate()->factory()->the_hole_value()); | 3812 return new(zone()) Literal(isolate()->factory()->the_hole_value()); |
| 3802 } | 3813 } |
| 3803 | 3814 |
| 3804 | 3815 |
| 3805 Literal* Parser::GetLiteralNumber(double value) { | 3816 Literal* Parser::GetLiteralNumber(double value) { |
| 3806 return NewNumberLiteral(value); | 3817 return NewNumberLiteral(value); |
| 3807 } | 3818 } |
| 3808 | 3819 |
| 3809 | 3820 |
| 3810 Handle<String> Parser::ParseIdentifier(bool* ok) { | 3821 Handle<String> Parser::ParseIdentifier(bool* ok) { |
| 3811 bool is_reserved; | 3822 bool is_reserved; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3939 // target stack has been used from the top of the target stack. Add | 3950 // target stack has been used from the top of the target stack. Add |
| 3940 // the break target to any TargetCollectors passed on the stack. | 3951 // the break target to any TargetCollectors passed on the stack. |
| 3941 for (Target* t = target_stack_; t != stop; t = t->previous()) { | 3952 for (Target* t = target_stack_; t != stop; t = t->previous()) { |
| 3942 TargetCollector* collector = t->node()->AsTargetCollector(); | 3953 TargetCollector* collector = t->node()->AsTargetCollector(); |
| 3943 if (collector != NULL) collector->AddTarget(target); | 3954 if (collector != NULL) collector->AddTarget(target); |
| 3944 } | 3955 } |
| 3945 } | 3956 } |
| 3946 | 3957 |
| 3947 | 3958 |
| 3948 Literal* Parser::NewNumberLiteral(double number) { | 3959 Literal* Parser::NewNumberLiteral(double number) { |
| 3949 return new Literal(isolate()->factory()->NewNumber(number, TENURED)); | 3960 return new(zone()) Literal(isolate()->factory()->NewNumber(number, TENURED)); |
| 3950 } | 3961 } |
| 3951 | 3962 |
| 3952 | 3963 |
| 3953 Expression* Parser::NewThrowReferenceError(Handle<String> type) { | 3964 Expression* Parser::NewThrowReferenceError(Handle<String> type) { |
| 3954 return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(), | 3965 return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(), |
| 3955 type, HandleVector<Object>(NULL, 0)); | 3966 type, HandleVector<Object>(NULL, 0)); |
| 3956 } | 3967 } |
| 3957 | 3968 |
| 3958 | 3969 |
| 3959 Expression* Parser::NewThrowSyntaxError(Handle<String> type, | 3970 Expression* Parser::NewThrowSyntaxError(Handle<String> type, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 3986 for (int i = 0; i < argc; i++) { | 3997 for (int i = 0; i < argc; i++) { |
| 3987 Handle<Object> element = arguments[i]; | 3998 Handle<Object> element = arguments[i]; |
| 3988 if (!element.is_null()) { | 3999 if (!element.is_null()) { |
| 3989 elements->set(i, *element); | 4000 elements->set(i, *element); |
| 3990 } | 4001 } |
| 3991 } | 4002 } |
| 3992 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(elements, | 4003 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(elements, |
| 3993 TENURED); | 4004 TENURED); |
| 3994 | 4005 |
| 3995 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); | 4006 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); |
| 3996 args->Add(new Literal(type)); | 4007 args->Add(new(zone()) Literal(type)); |
| 3997 args->Add(new Literal(array)); | 4008 args->Add(new(zone()) Literal(array)); |
| 3998 return new Throw(new CallRuntime(constructor, NULL, args), | 4009 return new(zone()) Throw(new(zone()) CallRuntime(constructor, NULL, args), |
| 3999 scanner().location().beg_pos); | 4010 scanner().location().beg_pos); |
| 4000 } | 4011 } |
| 4001 | 4012 |
| 4002 // ---------------------------------------------------------------------------- | 4013 // ---------------------------------------------------------------------------- |
| 4003 // JSON | 4014 // JSON |
| 4004 | 4015 |
| 4005 Handle<Object> JsonParser::ParseJson(Handle<String> script, | 4016 Handle<Object> JsonParser::ParseJson(Handle<String> script, |
| 4006 UC16CharacterStream* source) { | 4017 UC16CharacterStream* source) { |
| 4007 scanner_.Initialize(source); | 4018 scanner_.Initialize(source); |
| 4008 stack_overflow_ = false; | 4019 stack_overflow_ = false; |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4311 | 4322 |
| 4312 int capture_index = stored_state->capture_index(); | 4323 int capture_index = stored_state->capture_index(); |
| 4313 SubexpressionType type = stored_state->group_type(); | 4324 SubexpressionType type = stored_state->group_type(); |
| 4314 | 4325 |
| 4315 // Restore previous state. | 4326 // Restore previous state. |
| 4316 stored_state = stored_state->previous_state(); | 4327 stored_state = stored_state->previous_state(); |
| 4317 builder = stored_state->builder(); | 4328 builder = stored_state->builder(); |
| 4318 | 4329 |
| 4319 // Build result of subexpression. | 4330 // Build result of subexpression. |
| 4320 if (type == CAPTURE) { | 4331 if (type == CAPTURE) { |
| 4321 RegExpCapture* capture = new RegExpCapture(body, capture_index); | 4332 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index); |
| 4322 captures_->at(capture_index - 1) = capture; | 4333 captures_->at(capture_index - 1) = capture; |
| 4323 body = capture; | 4334 body = capture; |
| 4324 } else if (type != GROUPING) { | 4335 } else if (type != GROUPING) { |
| 4325 ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD); | 4336 ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD); |
| 4326 bool is_positive = (type == POSITIVE_LOOKAHEAD); | 4337 bool is_positive = (type == POSITIVE_LOOKAHEAD); |
| 4327 body = new RegExpLookahead(body, | 4338 body = new(zone()) RegExpLookahead(body, |
| 4328 is_positive, | 4339 is_positive, |
| 4329 end_capture_index - capture_index, | 4340 end_capture_index - capture_index, |
| 4330 capture_index); | 4341 capture_index); |
| 4331 } | 4342 } |
| 4332 builder->AddAtom(body); | 4343 builder->AddAtom(body); |
| 4333 // For compatability with JSC and ES3, we allow quantifiers after | 4344 // For compatability with JSC and ES3, we allow quantifiers after |
| 4334 // lookaheads, and break in all cases. | 4345 // lookaheads, and break in all cases. |
| 4335 break; | 4346 break; |
| 4336 } | 4347 } |
| 4337 case '|': { | 4348 case '|': { |
| 4338 Advance(); | 4349 Advance(); |
| 4339 builder->NewAlternative(); | 4350 builder->NewAlternative(); |
| 4340 continue; | 4351 continue; |
| 4341 } | 4352 } |
| 4342 case '*': | 4353 case '*': |
| 4343 case '+': | 4354 case '+': |
| 4344 case '?': | 4355 case '?': |
| 4345 return ReportError(CStrVector("Nothing to repeat")); | 4356 return ReportError(CStrVector("Nothing to repeat")); |
| 4346 case '^': { | 4357 case '^': { |
| 4347 Advance(); | 4358 Advance(); |
| 4348 if (multiline_) { | 4359 if (multiline_) { |
| 4349 builder->AddAssertion( | 4360 builder->AddAssertion( |
| 4350 new RegExpAssertion(RegExpAssertion::START_OF_LINE)); | 4361 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE)); |
| 4351 } else { | 4362 } else { |
| 4352 builder->AddAssertion( | 4363 builder->AddAssertion( |
| 4353 new RegExpAssertion(RegExpAssertion::START_OF_INPUT)); | 4364 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT)); |
| 4354 set_contains_anchor(); | 4365 set_contains_anchor(); |
| 4355 } | 4366 } |
| 4356 continue; | 4367 continue; |
| 4357 } | 4368 } |
| 4358 case '$': { | 4369 case '$': { |
| 4359 Advance(); | 4370 Advance(); |
| 4360 RegExpAssertion::Type type = | 4371 RegExpAssertion::Type type = |
| 4361 multiline_ ? RegExpAssertion::END_OF_LINE : | 4372 multiline_ ? RegExpAssertion::END_OF_LINE : |
| 4362 RegExpAssertion::END_OF_INPUT; | 4373 RegExpAssertion::END_OF_INPUT; |
| 4363 builder->AddAssertion(new RegExpAssertion(type)); | 4374 builder->AddAssertion(new(zone()) RegExpAssertion(type)); |
| 4364 continue; | 4375 continue; |
| 4365 } | 4376 } |
| 4366 case '.': { | 4377 case '.': { |
| 4367 Advance(); | 4378 Advance(); |
| 4368 // everything except \x0a, \x0d, \u2028 and \u2029 | 4379 // everything except \x0a, \x0d, \u2028 and \u2029 |
| 4369 ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); | 4380 ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); |
| 4370 CharacterRange::AddClassEscape('.', ranges); | 4381 CharacterRange::AddClassEscape('.', ranges); |
| 4371 RegExpTree* atom = new RegExpCharacterClass(ranges, false); | 4382 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); |
| 4372 builder->AddAtom(atom); | 4383 builder->AddAtom(atom); |
| 4373 break; | 4384 break; |
| 4374 } | 4385 } |
| 4375 case '(': { | 4386 case '(': { |
| 4376 SubexpressionType type = CAPTURE; | 4387 SubexpressionType type = CAPTURE; |
| 4377 Advance(); | 4388 Advance(); |
| 4378 if (current() == '?') { | 4389 if (current() == '?') { |
| 4379 switch (Next()) { | 4390 switch (Next()) { |
| 4380 case ':': | 4391 case ':': |
| 4381 type = GROUPING; | 4392 type = GROUPING; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 4394 } else { | 4405 } else { |
| 4395 if (captures_ == NULL) { | 4406 if (captures_ == NULL) { |
| 4396 captures_ = new ZoneList<RegExpCapture*>(2); | 4407 captures_ = new ZoneList<RegExpCapture*>(2); |
| 4397 } | 4408 } |
| 4398 if (captures_started() >= kMaxCaptures) { | 4409 if (captures_started() >= kMaxCaptures) { |
| 4399 ReportError(CStrVector("Too many captures") CHECK_FAILED); | 4410 ReportError(CStrVector("Too many captures") CHECK_FAILED); |
| 4400 } | 4411 } |
| 4401 captures_->Add(NULL); | 4412 captures_->Add(NULL); |
| 4402 } | 4413 } |
| 4403 // Store current state and begin new disjunction parsing. | 4414 // Store current state and begin new disjunction parsing. |
| 4404 stored_state = new RegExpParserState(stored_state, | 4415 stored_state = new(zone()) RegExpParserState(stored_state, |
| 4405 type, | 4416 type, |
| 4406 captures_started()); | 4417 captures_started()); |
| 4407 builder = stored_state->builder(); | 4418 builder = stored_state->builder(); |
| 4408 continue; | 4419 continue; |
| 4409 } | 4420 } |
| 4410 case '[': { | 4421 case '[': { |
| 4411 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED); | 4422 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED); |
| 4412 builder->AddAtom(atom); | 4423 builder->AddAtom(atom); |
| 4413 break; | 4424 break; |
| 4414 } | 4425 } |
| 4415 // Atom :: | 4426 // Atom :: |
| 4416 // \ AtomEscape | 4427 // \ AtomEscape |
| 4417 case '\\': | 4428 case '\\': |
| 4418 switch (Next()) { | 4429 switch (Next()) { |
| 4419 case kEndMarker: | 4430 case kEndMarker: |
| 4420 return ReportError(CStrVector("\\ at end of pattern")); | 4431 return ReportError(CStrVector("\\ at end of pattern")); |
| 4421 case 'b': | 4432 case 'b': |
| 4422 Advance(2); | 4433 Advance(2); |
| 4423 builder->AddAssertion( | 4434 builder->AddAssertion( |
| 4424 new RegExpAssertion(RegExpAssertion::BOUNDARY)); | 4435 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY)); |
| 4425 continue; | 4436 continue; |
| 4426 case 'B': | 4437 case 'B': |
| 4427 Advance(2); | 4438 Advance(2); |
| 4428 builder->AddAssertion( | 4439 builder->AddAssertion( |
| 4429 new RegExpAssertion(RegExpAssertion::NON_BOUNDARY)); | 4440 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY)); |
| 4430 continue; | 4441 continue; |
| 4431 // AtomEscape :: | 4442 // AtomEscape :: |
| 4432 // CharacterClassEscape | 4443 // CharacterClassEscape |
| 4433 // | 4444 // |
| 4434 // CharacterClassEscape :: one of | 4445 // CharacterClassEscape :: one of |
| 4435 // d D s S w W | 4446 // d D s S w W |
| 4436 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': { | 4447 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': { |
| 4437 uc32 c = Next(); | 4448 uc32 c = Next(); |
| 4438 Advance(2); | 4449 Advance(2); |
| 4439 ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); | 4450 ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); |
| 4440 CharacterRange::AddClassEscape(c, ranges); | 4451 CharacterRange::AddClassEscape(c, ranges); |
| 4441 RegExpTree* atom = new RegExpCharacterClass(ranges, false); | 4452 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); |
| 4442 builder->AddAtom(atom); | 4453 builder->AddAtom(atom); |
| 4443 break; | 4454 break; |
| 4444 } | 4455 } |
| 4445 case '1': case '2': case '3': case '4': case '5': case '6': | 4456 case '1': case '2': case '3': case '4': case '5': case '6': |
| 4446 case '7': case '8': case '9': { | 4457 case '7': case '8': case '9': { |
| 4447 int index = 0; | 4458 int index = 0; |
| 4448 if (ParseBackReferenceIndex(&index)) { | 4459 if (ParseBackReferenceIndex(&index)) { |
| 4449 RegExpCapture* capture = NULL; | 4460 RegExpCapture* capture = NULL; |
| 4450 if (captures_ != NULL && index <= captures_->length()) { | 4461 if (captures_ != NULL && index <= captures_->length()) { |
| 4451 capture = captures_->at(index - 1); | 4462 capture = captures_->at(index - 1); |
| 4452 } | 4463 } |
| 4453 if (capture == NULL) { | 4464 if (capture == NULL) { |
| 4454 builder->AddEmpty(); | 4465 builder->AddEmpty(); |
| 4455 break; | 4466 break; |
| 4456 } | 4467 } |
| 4457 RegExpTree* atom = new RegExpBackReference(capture); | 4468 RegExpTree* atom = new(zone()) RegExpBackReference(capture); |
| 4458 builder->AddAtom(atom); | 4469 builder->AddAtom(atom); |
| 4459 break; | 4470 break; |
| 4460 } | 4471 } |
| 4461 uc32 first_digit = Next(); | 4472 uc32 first_digit = Next(); |
| 4462 if (first_digit == '8' || first_digit == '9') { | 4473 if (first_digit == '8' || first_digit == '9') { |
| 4463 // Treat as identity escape | 4474 // Treat as identity escape |
| 4464 builder->AddCharacter(first_digit); | 4475 builder->AddCharacter(first_digit); |
| 4465 Advance(2); | 4476 Advance(2); |
| 4466 break; | 4477 break; |
| 4467 } | 4478 } |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4965 } | 4976 } |
| 4966 } | 4977 } |
| 4967 if (!has_more()) { | 4978 if (!has_more()) { |
| 4968 return ReportError(CStrVector(kUnterminated) CHECK_FAILED); | 4979 return ReportError(CStrVector(kUnterminated) CHECK_FAILED); |
| 4969 } | 4980 } |
| 4970 Advance(); | 4981 Advance(); |
| 4971 if (ranges->length() == 0) { | 4982 if (ranges->length() == 0) { |
| 4972 ranges->Add(CharacterRange::Everything()); | 4983 ranges->Add(CharacterRange::Everything()); |
| 4973 is_negated = !is_negated; | 4984 is_negated = !is_negated; |
| 4974 } | 4985 } |
| 4975 return new RegExpCharacterClass(ranges, is_negated); | 4986 return new(zone()) RegExpCharacterClass(ranges, is_negated); |
| 4976 } | 4987 } |
| 4977 | 4988 |
| 4978 | 4989 |
| 4979 // ---------------------------------------------------------------------------- | 4990 // ---------------------------------------------------------------------------- |
| 4980 // The Parser interface. | 4991 // The Parser interface. |
| 4981 | 4992 |
| 4982 ParserMessage::~ParserMessage() { | 4993 ParserMessage::~ParserMessage() { |
| 4983 for (int i = 0; i < args().length(); i++) | 4994 for (int i = 0; i < args().length(); i++) |
| 4984 DeleteArray(args()[i]); | 4995 DeleteArray(args()[i]); |
| 4985 DeleteArray(args().start()); | 4996 DeleteArray(args().start()); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5148 info->is_global(), | 5159 info->is_global(), |
| 5149 info->StrictMode()); | 5160 info->StrictMode()); |
| 5150 } | 5161 } |
| 5151 } | 5162 } |
| 5152 | 5163 |
| 5153 info->SetFunction(result); | 5164 info->SetFunction(result); |
| 5154 return (result != NULL); | 5165 return (result != NULL); |
| 5155 } | 5166 } |
| 5156 | 5167 |
| 5157 } } // namespace v8::internal | 5168 } } // namespace v8::internal |
| OLD | NEW |