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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 Handle<FixedArray> this_property_assignments() { | 276 Handle<FixedArray> this_property_assignments() { |
| 277 return this_property_assignments_; | 277 return this_property_assignments_; |
| 278 } | 278 } |
| 279 | 279 |
| 280 void AddProperty() { expected_property_count_++; } | 280 void AddProperty() { expected_property_count_++; } |
| 281 int expected_property_count() { return expected_property_count_; } | 281 int expected_property_count() { return expected_property_count_; } |
| 282 | 282 |
| 283 void AddLoop() { loop_count_++; } | 283 void AddLoop() { loop_count_++; } |
| 284 bool ContainsLoops() const { return loop_count_ > 0; } | 284 bool ContainsLoops() const { return loop_count_ > 0; } |
| 285 | 285 |
| 286 bool StrictMode() { return strict_mode_; } | |
| 287 void EnableStrictMode() { | |
| 288 strict_mode_ = FLAG_strict_mode; | |
| 289 } | |
| 290 | |
| 291 // Checks whether scope already declares parameter with a name "param_name". | |
| 292 bool CheckParameterDeclared(Scope *scope, Handle<String> param_name); | |
| 293 | |
| 286 private: | 294 private: |
| 287 // Captures the number of literals that need materialization in the | 295 // Captures the number of literals that need materialization in the |
| 288 // function. Includes regexp literals, and boilerplate for object | 296 // function. Includes regexp literals, and boilerplate for object |
| 289 // and array literals. | 297 // and array literals. |
| 290 int materialized_literal_count_; | 298 int materialized_literal_count_; |
| 291 | 299 |
| 292 // Properties count estimation. | 300 // Properties count estimation. |
| 293 int expected_property_count_; | 301 int expected_property_count_; |
| 294 | 302 |
| 295 // Keeps track of assignments to properties of this. Used for | 303 // Keeps track of assignments to properties of this. Used for |
| 296 // optimizing constructors. | 304 // optimizing constructors. |
| 297 bool only_simple_this_property_assignments_; | 305 bool only_simple_this_property_assignments_; |
| 298 Handle<FixedArray> this_property_assignments_; | 306 Handle<FixedArray> this_property_assignments_; |
| 299 | 307 |
| 300 // Captures the number of loops inside the scope. | 308 // Captures the number of loops inside the scope. |
| 301 int loop_count_; | 309 int loop_count_; |
| 302 | 310 |
| 311 // Parsing strict mode code. | |
| 312 bool strict_mode_; | |
| 313 | |
| 314 // Hash map for finding duplicate parameter names | |
| 315 HashMap* param_names_; | |
| 316 | |
| 303 // Bookkeeping | 317 // Bookkeeping |
| 304 TemporaryScope** variable_; | 318 TemporaryScope** variable_; |
| 305 TemporaryScope* parent_; | 319 TemporaryScope* parent_; |
| 306 }; | 320 }; |
| 307 | 321 |
| 308 | 322 |
| 309 TemporaryScope::TemporaryScope(TemporaryScope** variable) | 323 TemporaryScope::TemporaryScope(TemporaryScope** variable) |
| 310 : materialized_literal_count_(0), | 324 : materialized_literal_count_(0), |
| 311 expected_property_count_(0), | 325 expected_property_count_(0), |
| 312 only_simple_this_property_assignments_(false), | 326 only_simple_this_property_assignments_(false), |
| 313 this_property_assignments_(Factory::empty_fixed_array()), | 327 this_property_assignments_(Factory::empty_fixed_array()), |
| 314 loop_count_(0), | 328 loop_count_(0), |
| 329 param_names_(NULL), | |
| 315 variable_(variable), | 330 variable_(variable), |
| 316 parent_(*variable) { | 331 parent_(*variable) { |
| 332 // Inherit the strict mode from the parent scope. | |
| 333 strict_mode_ = (parent_ != NULL) ? parent_->strict_mode_ : false; | |
| 317 *variable = this; | 334 *variable = this; |
| 318 } | 335 } |
| 319 | 336 |
| 320 | 337 |
| 321 TemporaryScope::~TemporaryScope() { | 338 TemporaryScope::~TemporaryScope() { |
| 339 if (param_names_) { | |
| 340 // TODO(mmaly): How to allocate temporary map and free it when not needed? | |
|
Martin Maly
2011/01/14 00:06:28
I am trying to allocate the hash map only when fun
| |
| 341 // delete param_names_; | |
| 342 param_names_ = 0; | |
| 343 } | |
| 322 *variable_ = parent_; | 344 *variable_ = parent_; |
| 323 } | 345 } |
| 324 | 346 |
| 347 bool TemporaryScope::CheckParameterDeclared( | |
| 348 Scope *scope, Handle<String> param_name) { | |
| 349 | |
| 350 const int LinearLookupThreshold = 5; | |
| 351 | |
|
Martin Maly
2011/01/14 00:06:28
Moved the code from Scope to TemporaryScope since
| |
| 352 int length = scope->num_parameters(); | |
| 353 if (length <= LinearLookupThreshold) { | |
| 354 for (int i = 0; i < length; i ++) { | |
| 355 if (param_name.is_identical_to(scope->parameter(i)->name())) { | |
| 356 // Parameter with the given name found! | |
| 357 return true; | |
| 358 } | |
| 359 } | |
| 360 } else { | |
| 361 if (param_names_ == NULL) { | |
| 362 // Populate the variable map. | |
| 363 param_names_ = new VariableMap(); | |
| 364 for (int i = 0; i < length; i ++) { | |
| 365 Handle<String> name = scope->parameter(i)->name(); | |
| 366 HashMap::Entry* e = param_names_->Lookup( | |
| 367 name.location(), name->Hash(), true); | |
| 368 ASSERT(e->value == NULL); | |
| 369 e->value = name.location(); | |
| 370 } | |
| 371 } | |
| 372 | |
| 373 HashMap::Entry* p = param_names_->Lookup( | |
| 374 param_name.location(), param_name->Hash(), true); | |
| 375 if (p->value == NULL) { | |
| 376 p->value = param_name.location(); | |
| 377 } else { | |
| 378 // Parameter with the given name found! | |
| 379 return true; | |
| 380 } | |
| 381 } | |
| 382 return false; | |
| 383 } | |
| 384 | |
| 325 | 385 |
| 326 Handle<String> Parser::LookupSymbol(int symbol_id) { | 386 Handle<String> Parser::LookupSymbol(int symbol_id) { |
| 327 // Length of symbol cache is the number of identified symbols. | 387 // Length of symbol cache is the number of identified symbols. |
| 328 // If we are larger than that, or negative, it's not a cached symbol. | 388 // If we are larger than that, or negative, it's not a cached symbol. |
| 329 // This might also happen if there is no preparser symbol data, even | 389 // This might also happen if there is no preparser symbol data, even |
| 330 // if there is some preparser data. | 390 // if there is some preparser data. |
| 331 if (static_cast<unsigned>(symbol_id) | 391 if (static_cast<unsigned>(symbol_id) |
| 332 >= static_cast<unsigned>(symbol_cache_.length())) { | 392 >= static_cast<unsigned>(symbol_cache_.length())) { |
| 333 if (scanner().is_literal_ascii()) { | 393 if (scanner().is_literal_ascii()) { |
| 334 return Factory::LookupAsciiSymbol(scanner().literal_ascii_string()); | 394 return Factory::LookupAsciiSymbol(scanner().literal_ascii_string()); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 554 *with_nesting_level_variable_ = prev_level_; | 614 *with_nesting_level_variable_ = prev_level_; |
| 555 } | 615 } |
| 556 | 616 |
| 557 private: | 617 private: |
| 558 Scope** scope_variable_; | 618 Scope** scope_variable_; |
| 559 int* with_nesting_level_variable_; | 619 int* with_nesting_level_variable_; |
| 560 Scope* prev_scope_; | 620 Scope* prev_scope_; |
| 561 int prev_level_; | 621 int prev_level_; |
| 562 }; | 622 }; |
| 563 | 623 |
| 564 | |
| 565 // ---------------------------------------------------------------------------- | 624 // ---------------------------------------------------------------------------- |
| 566 // The CHECK_OK macro is a convenient macro to enforce error | 625 // The CHECK_OK macro is a convenient macro to enforce error |
| 567 // handling for functions that may fail (by returning !*ok). | 626 // handling for functions that may fail (by returning !*ok). |
| 568 // | 627 // |
| 569 // CAUTION: This macro appends extra statements after a call, | 628 // CAUTION: This macro appends extra statements after a call, |
| 570 // thus it must never be used where only a single statement | 629 // thus it must never be used where only a single statement |
| 571 // is correct (e.g. an if statement branch w/o braces)! | 630 // is correct (e.g. an if statement branch w/o braces)! |
| 572 | 631 |
| 573 #define CHECK_OK ok); \ | 632 #define CHECK_OK ok); \ |
| 574 if (!*ok) return NULL; \ | 633 if (!*ok) return NULL; \ |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 top_scope_, | 720 top_scope_, |
| 662 body, | 721 body, |
| 663 temp_scope.materialized_literal_count(), | 722 temp_scope.materialized_literal_count(), |
| 664 temp_scope.expected_property_count(), | 723 temp_scope.expected_property_count(), |
| 665 temp_scope.only_simple_this_property_assignments(), | 724 temp_scope.only_simple_this_property_assignments(), |
| 666 temp_scope.this_property_assignments(), | 725 temp_scope.this_property_assignments(), |
| 667 0, | 726 0, |
| 668 0, | 727 0, |
| 669 source->length(), | 728 source->length(), |
| 670 false, | 729 false, |
| 671 temp_scope.ContainsLoops()); | 730 temp_scope.ContainsLoops(), |
| 731 temp_scope.StrictMode()); | |
| 672 } else if (stack_overflow_) { | 732 } else if (stack_overflow_) { |
| 673 Top::StackOverflow(); | 733 Top::StackOverflow(); |
| 674 } | 734 } |
| 675 } | 735 } |
| 676 | 736 |
| 677 // Make sure the target stack is empty. | 737 // Make sure the target stack is empty. |
| 678 ASSERT(target_stack_ == NULL); | 738 ASSERT(target_stack_ == NULL); |
| 679 | 739 |
| 680 // If there was a syntax error we have to get rid of the AST | 740 // If there was a syntax error we have to get rid of the AST |
| 681 // and it is not safe to do so before the scope has been deleted. | 741 // and it is not safe to do so before the scope has been deleted. |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1051 | 1111 |
| 1052 // Allocate a target stack to use for this set of source | 1112 // Allocate a target stack to use for this set of source |
| 1053 // elements. This way, all scripts and functions get their own | 1113 // elements. This way, all scripts and functions get their own |
| 1054 // target stack thus avoiding illegal breaks and continues across | 1114 // target stack thus avoiding illegal breaks and continues across |
| 1055 // functions. | 1115 // functions. |
| 1056 TargetScope scope(&this->target_stack_); | 1116 TargetScope scope(&this->target_stack_); |
| 1057 | 1117 |
| 1058 ASSERT(processor != NULL); | 1118 ASSERT(processor != NULL); |
| 1059 InitializationBlockFinder block_finder; | 1119 InitializationBlockFinder block_finder; |
| 1060 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; | 1120 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; |
| 1121 bool directive_prologue = true; // Parsing directive prologue. | |
| 1122 | |
| 1061 while (peek() != end_token) { | 1123 while (peek() != end_token) { |
| 1062 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1124 Statement* stat; |
| 1125 | |
| 1126 if (directive_prologue && peek() == Token::STRING) { | |
| 1127 // A shot at a directive. | |
| 1128 Scanner::Location directive_loc = scanner().peek_location(); | |
| 1129 stat = ParseStatement(NULL, CHECK_OK); | |
| 1130 if (stat == NULL || stat->IsEmpty()) { | |
| 1131 directive_prologue = false; // End of directive prologue. | |
| 1132 continue; | |
| 1133 } | |
| 1134 | |
| 1135 if (directive_prologue) { | |
| 1136 ExpressionStatement *e_stat; | |
| 1137 Literal *literal; | |
| 1138 // Still processing directive prologue? | |
| 1139 if ((e_stat = stat->AsExpressionStatement()) != NULL && | |
| 1140 (literal = e_stat->expression()->AsLiteral()) != NULL && | |
| 1141 literal->handle()->IsString()) { | |
| 1142 Handle<String> directive = Handle<String>::cast(literal->handle()); | |
| 1143 | |
| 1144 // Check "use strict" directive (ES5 14.1). | |
| 1145 if (!temp_scope_->StrictMode() && | |
| 1146 directive->Equals(Heap::use_strict()) && | |
| 1147 directive_loc.end_pos - directive_loc.beg_pos == | |
| 1148 Heap::use_strict()->length() + 2) { | |
| 1149 temp_scope_->EnableStrictMode(); | |
| 1150 } | |
| 1151 } else { | |
| 1152 // End of the directive prologue. | |
| 1153 directive_prologue = false; | |
| 1154 } | |
| 1155 } | |
| 1156 } else { | |
| 1157 stat = ParseStatement(NULL, CHECK_OK); | |
| 1158 } | |
| 1159 | |
| 1063 if (stat == NULL || stat->IsEmpty()) continue; | 1160 if (stat == NULL || stat->IsEmpty()) continue; |
| 1064 // We find and mark the initialization blocks on top level code only. | 1161 // We find and mark the initialization blocks on top level code only. |
| 1065 // This is because the optimization prevents reuse of the map transitions, | 1162 // This is because the optimization prevents reuse of the map transitions, |
| 1066 // so it should be used only for code that will only be run once. | 1163 // so it should be used only for code that will only be run once. |
| 1067 if (top_scope_->is_global_scope()) { | 1164 if (top_scope_->is_global_scope()) { |
| 1068 block_finder.Update(stat); | 1165 block_finder.Update(stat); |
| 1069 } | 1166 } |
| 1070 // Find and mark all assignments to named properties in this (this.x =) | 1167 // Find and mark all assignments to named properties in this (this.x =) |
| 1071 if (top_scope_->is_function_scope()) { | 1168 if (top_scope_->is_function_scope()) { |
| 1072 this_property_assignment_finder.Update(top_scope_, stat); | 1169 this_property_assignment_finder.Update(top_scope_, stat); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1407 Block* Parser::ParseVariableStatement(bool* ok) { | 1504 Block* Parser::ParseVariableStatement(bool* ok) { |
| 1408 // VariableStatement :: | 1505 // VariableStatement :: |
| 1409 // VariableDeclarations ';' | 1506 // VariableDeclarations ';' |
| 1410 | 1507 |
| 1411 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature | 1508 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature |
| 1412 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK); | 1509 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK); |
| 1413 ExpectSemicolon(CHECK_OK); | 1510 ExpectSemicolon(CHECK_OK); |
| 1414 return result; | 1511 return result; |
| 1415 } | 1512 } |
| 1416 | 1513 |
| 1514 static bool IsEvalOrArguments(Handle<String> string) { | |
| 1515 return string.is_identical_to(Factory::eval_symbol()) || | |
| 1516 string.is_identical_to(Factory::arguments_symbol()); | |
| 1517 } | |
| 1417 | 1518 |
| 1418 // If the variable declaration declares exactly one non-const | 1519 // If the variable declaration declares exactly one non-const |
| 1419 // variable, then *var is set to that variable. In all other cases, | 1520 // variable, then *var is set to that variable. In all other cases, |
| 1420 // *var is untouched; in particular, it is the caller's responsibility | 1521 // *var is untouched; in particular, it is the caller's responsibility |
| 1421 // to initialize it properly. This mechanism is used for the parsing | 1522 // to initialize it properly. This mechanism is used for the parsing |
| 1422 // of 'for-in' loops. | 1523 // of 'for-in' loops. |
| 1423 Block* Parser::ParseVariableDeclarations(bool accept_IN, | 1524 Block* Parser::ParseVariableDeclarations(bool accept_IN, |
| 1424 Expression** var, | 1525 Expression** var, |
| 1425 bool* ok) { | 1526 bool* ok) { |
| 1426 // VariableDeclarations :: | 1527 // VariableDeclarations :: |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1455 VariableProxy* last_var = NULL; // the last variable declared | 1556 VariableProxy* last_var = NULL; // the last variable declared |
| 1456 int nvars = 0; // the number of variables declared | 1557 int nvars = 0; // the number of variables declared |
| 1457 do { | 1558 do { |
| 1458 if (fni_ != NULL) fni_->Enter(); | 1559 if (fni_ != NULL) fni_->Enter(); |
| 1459 | 1560 |
| 1460 // Parse variable name. | 1561 // Parse variable name. |
| 1461 if (nvars > 0) Consume(Token::COMMA); | 1562 if (nvars > 0) Consume(Token::COMMA); |
| 1462 Handle<String> name = ParseIdentifier(CHECK_OK); | 1563 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1463 if (fni_ != NULL) fni_->PushVariableName(name); | 1564 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1464 | 1565 |
| 1566 // Strict mode variables may not be named eval or arguments | |
| 1567 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { | |
| 1568 ReportMessage("strict_var_name", Vector<const char*>::empty()); | |
| 1569 *ok = false; | |
| 1570 return NULL; | |
| 1571 } | |
| 1572 | |
| 1465 // Declare variable. | 1573 // Declare variable. |
| 1466 // Note that we *always* must treat the initial value via a separate init | 1574 // Note that we *always* must treat the initial value via a separate init |
| 1467 // assignment for variables and constants because the value must be assigned | 1575 // assignment for variables and constants because the value must be assigned |
| 1468 // when the variable is encountered in the source. But the variable/constant | 1576 // when the variable is encountered in the source. But the variable/constant |
| 1469 // is declared (and set to 'undefined') upon entering the function within | 1577 // is declared (and set to 'undefined') upon entering the function within |
| 1470 // which the variable or constant is declared. Only function variables have | 1578 // which the variable or constant is declared. Only function variables have |
| 1471 // an initial value in the declaration (because they are initialized upon | 1579 // an initial value in the declaration (because they are initialized upon |
| 1472 // entering the function). | 1580 // entering the function). |
| 1473 // | 1581 // |
| 1474 // If we have a const declaration, in an inner scope, the proxy is always | 1582 // If we have a const declaration, in an inner scope, the proxy is always |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1807 } | 1915 } |
| 1808 return result; | 1916 return result; |
| 1809 } | 1917 } |
| 1810 | 1918 |
| 1811 | 1919 |
| 1812 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 1920 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 1813 // WithStatement :: | 1921 // WithStatement :: |
| 1814 // 'with' '(' Expression ')' Statement | 1922 // 'with' '(' Expression ')' Statement |
| 1815 | 1923 |
| 1816 Expect(Token::WITH, CHECK_OK); | 1924 Expect(Token::WITH, CHECK_OK); |
| 1925 | |
| 1926 if (temp_scope_->StrictMode()) { | |
| 1927 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | |
| 1928 *ok = false; | |
| 1929 return NULL; | |
| 1930 } | |
| 1931 | |
| 1817 Expect(Token::LPAREN, CHECK_OK); | 1932 Expect(Token::LPAREN, CHECK_OK); |
| 1818 Expression* expr = ParseExpression(true, CHECK_OK); | 1933 Expression* expr = ParseExpression(true, CHECK_OK); |
| 1819 Expect(Token::RPAREN, CHECK_OK); | 1934 Expect(Token::RPAREN, CHECK_OK); |
| 1820 | 1935 |
| 1821 return WithHelper(expr, labels, false, CHECK_OK); | 1936 return WithHelper(expr, labels, false, CHECK_OK); |
| 1822 } | 1937 } |
| 1823 | 1938 |
| 1824 | 1939 |
| 1825 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 1940 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
| 1826 // CaseClause :: | 1941 // CaseClause :: |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1939 // the jump targets. | 2054 // the jump targets. |
| 1940 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); | 2055 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); |
| 1941 TargetCollector catch_collector(catch_target_list); | 2056 TargetCollector catch_collector(catch_target_list); |
| 1942 bool has_catch = false; | 2057 bool has_catch = false; |
| 1943 if (tok == Token::CATCH) { | 2058 if (tok == Token::CATCH) { |
| 1944 has_catch = true; | 2059 has_catch = true; |
| 1945 Consume(Token::CATCH); | 2060 Consume(Token::CATCH); |
| 1946 | 2061 |
| 1947 Expect(Token::LPAREN, CHECK_OK); | 2062 Expect(Token::LPAREN, CHECK_OK); |
| 1948 Handle<String> name = ParseIdentifier(CHECK_OK); | 2063 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2064 | |
| 2065 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { | |
| 2066 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | |
| 2067 *ok = false; | |
| 2068 return NULL; | |
| 2069 } | |
| 2070 | |
| 1949 Expect(Token::RPAREN, CHECK_OK); | 2071 Expect(Token::RPAREN, CHECK_OK); |
| 1950 | 2072 |
| 1951 if (peek() == Token::LBRACE) { | 2073 if (peek() == Token::LBRACE) { |
| 1952 // Allocate a temporary for holding the finally state while | 2074 // Allocate a temporary for holding the finally state while |
| 1953 // executing the finally block. | 2075 // executing the finally block. |
| 1954 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); | 2076 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); |
| 1955 Literal* name_literal = new Literal(name); | 2077 Literal* name_literal = new Literal(name); |
| 1956 VariableProxy* catch_var_use = new VariableProxy(catch_var); | 2078 VariableProxy* catch_var_use = new VariableProxy(catch_var); |
| 1957 Expression* obj = new CatchExtensionObject(name_literal, catch_var_use); | 2079 Expression* obj = new CatchExtensionObject(name_literal, catch_var_use); |
| 1958 { Target target(&this->target_stack_, &catch_collector); | 2080 { Target target(&this->target_stack_, &catch_collector); |
| (...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3185 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); | 3307 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
| 3186 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 3308 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 3187 scope); | 3309 scope); |
| 3188 TemporaryScope temp_scope(&this->temp_scope_); | 3310 TemporaryScope temp_scope(&this->temp_scope_); |
| 3189 top_scope_->SetScopeName(name); | 3311 top_scope_->SetScopeName(name); |
| 3190 | 3312 |
| 3191 // FormalParameterList :: | 3313 // FormalParameterList :: |
| 3192 // '(' (Identifier)*[','] ')' | 3314 // '(' (Identifier)*[','] ')' |
| 3193 Expect(Token::LPAREN, CHECK_OK); | 3315 Expect(Token::LPAREN, CHECK_OK); |
| 3194 int start_pos = scanner().location().beg_pos; | 3316 int start_pos = scanner().location().beg_pos; |
| 3317 Scanner::Location eval_loc(RelocInfo::kNoPosition, RelocInfo::kNoPosition); | |
| 3318 Scanner::Location dupe_loc(RelocInfo::kNoPosition, RelocInfo::kNoPosition); | |
| 3319 | |
| 3195 bool done = (peek() == Token::RPAREN); | 3320 bool done = (peek() == Token::RPAREN); |
| 3196 while (!done) { | 3321 while (!done) { |
| 3197 Handle<String> param_name = ParseIdentifier(CHECK_OK); | 3322 Handle<String> param_name = ParseIdentifier(CHECK_OK); |
| 3198 top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, | 3323 Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR); |
| 3199 Variable::VAR)); | 3324 |
|
Martin Maly
2011/01/14 00:06:28
This code runs even when not processing strict mod
| |
| 3325 // Store locations for possible future error reports. | |
| 3326 if (eval_loc.beg_pos == RelocInfo::kNoPosition && | |
| 3327 IsEvalOrArguments(param_name)) { | |
| 3328 // Store location for later | |
| 3329 eval_loc = scanner().location(); | |
| 3330 } | |
| 3331 if (dupe_loc.beg_pos == RelocInfo::kNoPosition && | |
| 3332 temp_scope.CheckParameterDeclared(scope, param_name)) { | |
| 3333 // Store location for later | |
| 3334 dupe_loc = scanner().location(); | |
| 3335 } | |
| 3336 | |
| 3337 top_scope_->AddParameter(parameter); | |
| 3200 num_parameters++; | 3338 num_parameters++; |
| 3201 done = (peek() == Token::RPAREN); | 3339 done = (peek() == Token::RPAREN); |
| 3202 if (!done) Expect(Token::COMMA, CHECK_OK); | 3340 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3203 } | 3341 } |
| 3204 Expect(Token::RPAREN, CHECK_OK); | 3342 Expect(Token::RPAREN, CHECK_OK); |
| 3205 | 3343 |
| 3206 Expect(Token::LBRACE, CHECK_OK); | 3344 Expect(Token::LBRACE, CHECK_OK); |
| 3207 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); | 3345 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); |
| 3208 | 3346 |
| 3209 // If we have a named function expression, we add a local variable | 3347 // If we have a named function expression, we add a local variable |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3258 materialized_literal_count = temp_scope.materialized_literal_count(); | 3396 materialized_literal_count = temp_scope.materialized_literal_count(); |
| 3259 expected_property_count = temp_scope.expected_property_count(); | 3397 expected_property_count = temp_scope.expected_property_count(); |
| 3260 only_simple_this_property_assignments = | 3398 only_simple_this_property_assignments = |
| 3261 temp_scope.only_simple_this_property_assignments(); | 3399 temp_scope.only_simple_this_property_assignments(); |
| 3262 this_property_assignments = temp_scope.this_property_assignments(); | 3400 this_property_assignments = temp_scope.this_property_assignments(); |
| 3263 | 3401 |
| 3264 Expect(Token::RBRACE, CHECK_OK); | 3402 Expect(Token::RBRACE, CHECK_OK); |
| 3265 end_pos = scanner().location().end_pos; | 3403 end_pos = scanner().location().end_pos; |
| 3266 } | 3404 } |
| 3267 | 3405 |
| 3406 // Validate strict mode. | |
| 3407 if (temp_scope_->StrictMode()) { | |
| 3408 if (IsEvalOrArguments(name)) { | |
| 3409 int position = function_token_position != RelocInfo::kNoPosition | |
|
Martin Maly
2011/01/14 00:06:28
This is still necessary because property get/set g
| |
| 3410 ? function_token_position | |
| 3411 : (start_pos > 0 ? start_pos - 1 : start_pos); | |
| 3412 ReportMessageAt(Scanner::Location(position, start_pos), | |
| 3413 "strict_function_name", Vector<const char*>::empty()); | |
| 3414 *ok = false; | |
| 3415 return NULL; | |
| 3416 } | |
| 3417 if (eval_loc.beg_pos != RelocInfo::kNoPosition) { | |
| 3418 ReportMessageAt(eval_loc, "strict_param_name", | |
| 3419 Vector<const char*>::empty()); | |
| 3420 *ok = false; | |
| 3421 return NULL; | |
| 3422 } | |
| 3423 if (dupe_loc.beg_pos != RelocInfo::kNoPosition) { | |
| 3424 ReportMessageAt(dupe_loc, "strict_param_dupe", | |
| 3425 Vector<const char*>::empty()); | |
| 3426 *ok = false; | |
| 3427 return NULL; | |
| 3428 } | |
| 3429 // TODO(mmaly): Check for octal escape sequence here. | |
| 3430 } | |
| 3431 | |
| 3268 FunctionLiteral* function_literal = | 3432 FunctionLiteral* function_literal = |
| 3269 new FunctionLiteral(name, | 3433 new FunctionLiteral(name, |
| 3270 top_scope_, | 3434 top_scope_, |
| 3271 body, | 3435 body, |
| 3272 materialized_literal_count, | 3436 materialized_literal_count, |
| 3273 expected_property_count, | 3437 expected_property_count, |
| 3274 only_simple_this_property_assignments, | 3438 only_simple_this_property_assignments, |
| 3275 this_property_assignments, | 3439 this_property_assignments, |
| 3276 num_parameters, | 3440 num_parameters, |
| 3277 start_pos, | 3441 start_pos, |
| 3278 end_pos, | 3442 end_pos, |
| 3279 function_name->length() > 0, | 3443 function_name->length() > 0, |
| 3280 temp_scope.ContainsLoops()); | 3444 temp_scope.ContainsLoops(), |
| 3445 temp_scope.StrictMode()); | |
| 3281 function_literal->set_function_token_position(function_token_position); | 3446 function_literal->set_function_token_position(function_token_position); |
| 3282 | 3447 |
| 3283 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); | 3448 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); |
| 3284 return function_literal; | 3449 return function_literal; |
| 3285 } | 3450 } |
| 3286 } | 3451 } |
| 3287 | 3452 |
| 3288 | 3453 |
| 3289 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3454 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3290 // CallRuntime :: | 3455 // CallRuntime :: |
| (...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4695 Handle<String> source = Handle<String>(String::cast(script->source())); | 4860 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 4696 result = parser.ParseProgram(source, info->is_global()); | 4861 result = parser.ParseProgram(source, info->is_global()); |
| 4697 } | 4862 } |
| 4698 } | 4863 } |
| 4699 | 4864 |
| 4700 info->SetFunction(result); | 4865 info->SetFunction(result); |
| 4701 return (result != NULL); | 4866 return (result != NULL); |
| 4702 } | 4867 } |
| 4703 | 4868 |
| 4704 } } // namespace v8::internal | 4869 } } // namespace v8::internal |
| OLD | NEW |