| 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 |
| 286 private: | 291 private: |
| 287 // Captures the number of literals that need materialization in the | 292 // Captures the number of literals that need materialization in the |
| 288 // function. Includes regexp literals, and boilerplate for object | 293 // function. Includes regexp literals, and boilerplate for object |
| 289 // and array literals. | 294 // and array literals. |
| 290 int materialized_literal_count_; | 295 int materialized_literal_count_; |
| 291 | 296 |
| 292 // Properties count estimation. | 297 // Properties count estimation. |
| 293 int expected_property_count_; | 298 int expected_property_count_; |
| 294 | 299 |
| 295 // Keeps track of assignments to properties of this. Used for | 300 // Keeps track of assignments to properties of this. Used for |
| 296 // optimizing constructors. | 301 // optimizing constructors. |
| 297 bool only_simple_this_property_assignments_; | 302 bool only_simple_this_property_assignments_; |
| 298 Handle<FixedArray> this_property_assignments_; | 303 Handle<FixedArray> this_property_assignments_; |
| 299 | 304 |
| 300 // Captures the number of loops inside the scope. | 305 // Captures the number of loops inside the scope. |
| 301 int loop_count_; | 306 int loop_count_; |
| 302 | 307 |
| 308 // Parsing strict mode code. |
| 309 bool strict_mode_; |
| 310 |
| 303 // Bookkeeping | 311 // Bookkeeping |
| 304 TemporaryScope** variable_; | 312 TemporaryScope** variable_; |
| 305 TemporaryScope* parent_; | 313 TemporaryScope* parent_; |
| 306 }; | 314 }; |
| 307 | 315 |
| 308 | 316 |
| 309 TemporaryScope::TemporaryScope(TemporaryScope** variable) | 317 TemporaryScope::TemporaryScope(TemporaryScope** variable) |
| 310 : materialized_literal_count_(0), | 318 : materialized_literal_count_(0), |
| 311 expected_property_count_(0), | 319 expected_property_count_(0), |
| 312 only_simple_this_property_assignments_(false), | 320 only_simple_this_property_assignments_(false), |
| 313 this_property_assignments_(Factory::empty_fixed_array()), | 321 this_property_assignments_(Factory::empty_fixed_array()), |
| 314 loop_count_(0), | 322 loop_count_(0), |
| 315 variable_(variable), | 323 variable_(variable), |
| 316 parent_(*variable) { | 324 parent_(*variable) { |
| 325 // Inherit the strict mode from the parent scope. |
| 326 strict_mode_ = (parent_ != NULL) && parent_->strict_mode_; |
| 317 *variable = this; | 327 *variable = this; |
| 318 } | 328 } |
| 319 | 329 |
| 320 | 330 |
| 321 TemporaryScope::~TemporaryScope() { | 331 TemporaryScope::~TemporaryScope() { |
| 322 *variable_ = parent_; | 332 *variable_ = parent_; |
| 323 } | 333 } |
| 324 | 334 |
| 325 | 335 |
| 326 Handle<String> Parser::LookupSymbol(int symbol_id) { | 336 Handle<String> Parser::LookupSymbol(int symbol_id) { |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 *with_nesting_level_variable_ = prev_level_; | 564 *with_nesting_level_variable_ = prev_level_; |
| 555 } | 565 } |
| 556 | 566 |
| 557 private: | 567 private: |
| 558 Scope** scope_variable_; | 568 Scope** scope_variable_; |
| 559 int* with_nesting_level_variable_; | 569 int* with_nesting_level_variable_; |
| 560 Scope* prev_scope_; | 570 Scope* prev_scope_; |
| 561 int prev_level_; | 571 int prev_level_; |
| 562 }; | 572 }; |
| 563 | 573 |
| 564 | |
| 565 // ---------------------------------------------------------------------------- | 574 // ---------------------------------------------------------------------------- |
| 566 // The CHECK_OK macro is a convenient macro to enforce error | 575 // The CHECK_OK macro is a convenient macro to enforce error |
| 567 // handling for functions that may fail (by returning !*ok). | 576 // handling for functions that may fail (by returning !*ok). |
| 568 // | 577 // |
| 569 // CAUTION: This macro appends extra statements after a call, | 578 // CAUTION: This macro appends extra statements after a call, |
| 570 // thus it must never be used where only a single statement | 579 // thus it must never be used where only a single statement |
| 571 // is correct (e.g. an if statement branch w/o braces)! | 580 // is correct (e.g. an if statement branch w/o braces)! |
| 572 | 581 |
| 573 #define CHECK_OK ok); \ | 582 #define CHECK_OK ok); \ |
| 574 if (!*ok) return NULL; \ | 583 if (!*ok) return NULL; \ |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 662 top_scope_, | 671 top_scope_, |
| 663 body, | 672 body, |
| 664 temp_scope.materialized_literal_count(), | 673 temp_scope.materialized_literal_count(), |
| 665 temp_scope.expected_property_count(), | 674 temp_scope.expected_property_count(), |
| 666 temp_scope.only_simple_this_property_assignments(), | 675 temp_scope.only_simple_this_property_assignments(), |
| 667 temp_scope.this_property_assignments(), | 676 temp_scope.this_property_assignments(), |
| 668 0, | 677 0, |
| 669 0, | 678 0, |
| 670 source->length(), | 679 source->length(), |
| 671 false, | 680 false, |
| 672 temp_scope.ContainsLoops()); | 681 temp_scope.ContainsLoops(), |
| 682 temp_scope.StrictMode()); |
| 673 } else if (stack_overflow_) { | 683 } else if (stack_overflow_) { |
| 674 Top::StackOverflow(); | 684 Top::StackOverflow(); |
| 675 } | 685 } |
| 676 } | 686 } |
| 677 | 687 |
| 678 // Make sure the target stack is empty. | 688 // Make sure the target stack is empty. |
| 679 ASSERT(target_stack_ == NULL); | 689 ASSERT(target_stack_ == NULL); |
| 680 | 690 |
| 681 // If there was a syntax error we have to get rid of the AST | 691 // If there was a syntax error we have to get rid of the AST |
| 682 // and it is not safe to do so before the scope has been deleted. | 692 // and it is not safe to do so before the scope has been deleted. |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 | 1078 |
| 1069 // Allocate a target stack to use for this set of source | 1079 // Allocate a target stack to use for this set of source |
| 1070 // elements. This way, all scripts and functions get their own | 1080 // elements. This way, all scripts and functions get their own |
| 1071 // target stack thus avoiding illegal breaks and continues across | 1081 // target stack thus avoiding illegal breaks and continues across |
| 1072 // functions. | 1082 // functions. |
| 1073 TargetScope scope(&this->target_stack_); | 1083 TargetScope scope(&this->target_stack_); |
| 1074 | 1084 |
| 1075 ASSERT(processor != NULL); | 1085 ASSERT(processor != NULL); |
| 1076 InitializationBlockFinder block_finder; | 1086 InitializationBlockFinder block_finder; |
| 1077 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; | 1087 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; |
| 1088 bool directive_prologue = true; // Parsing directive prologue. |
| 1089 |
| 1078 while (peek() != end_token) { | 1090 while (peek() != end_token) { |
| 1091 if (directive_prologue && peek() != Token::STRING) { |
| 1092 directive_prologue = false; |
| 1093 } |
| 1094 |
| 1095 Scanner::Location token_loc = scanner().peek_location(); |
| 1079 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1096 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 1080 if (stat == NULL || stat->IsEmpty()) continue; | 1097 |
| 1098 if (stat == NULL || stat->IsEmpty()) { |
| 1099 directive_prologue = false; // End of directive prologue. |
| 1100 continue; |
| 1101 } |
| 1102 |
| 1103 if (directive_prologue) { |
| 1104 // A shot at a directive. |
| 1105 ExpressionStatement *e_stat; |
| 1106 Literal *literal; |
| 1107 // Still processing directive prologue? |
| 1108 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 1109 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 1110 literal->handle()->IsString()) { |
| 1111 Handle<String> directive = Handle<String>::cast(literal->handle()); |
| 1112 |
| 1113 // Check "use strict" directive (ES5 14.1). |
| 1114 if (!temp_scope_->StrictMode() && |
| 1115 directive->Equals(Heap::use_strict()) && |
| 1116 token_loc.end_pos - token_loc.beg_pos == |
| 1117 Heap::use_strict()->length() + 2) { |
| 1118 temp_scope_->EnableStrictMode(); |
| 1119 // "use strict" is the only directive for now. |
| 1120 directive_prologue = false; |
| 1121 } |
| 1122 } else { |
| 1123 // End of the directive prologue. |
| 1124 directive_prologue = false; |
| 1125 } |
| 1126 } |
| 1127 |
| 1081 // We find and mark the initialization blocks on top level code only. | 1128 // We find and mark the initialization blocks on top level code only. |
| 1082 // This is because the optimization prevents reuse of the map transitions, | 1129 // This is because the optimization prevents reuse of the map transitions, |
| 1083 // so it should be used only for code that will only be run once. | 1130 // so it should be used only for code that will only be run once. |
| 1084 if (top_scope_->is_global_scope()) { | 1131 if (top_scope_->is_global_scope()) { |
| 1085 block_finder.Update(stat); | 1132 block_finder.Update(stat); |
| 1086 } | 1133 } |
| 1087 // Find and mark all assignments to named properties in this (this.x =) | 1134 // Find and mark all assignments to named properties in this (this.x =) |
| 1088 if (top_scope_->is_function_scope()) { | 1135 if (top_scope_->is_function_scope()) { |
| 1089 this_property_assignment_finder.Update(top_scope_, stat); | 1136 this_property_assignment_finder.Update(top_scope_, stat); |
| 1090 } | 1137 } |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1424 Block* Parser::ParseVariableStatement(bool* ok) { | 1471 Block* Parser::ParseVariableStatement(bool* ok) { |
| 1425 // VariableStatement :: | 1472 // VariableStatement :: |
| 1426 // VariableDeclarations ';' | 1473 // VariableDeclarations ';' |
| 1427 | 1474 |
| 1428 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature | 1475 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature |
| 1429 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK); | 1476 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK); |
| 1430 ExpectSemicolon(CHECK_OK); | 1477 ExpectSemicolon(CHECK_OK); |
| 1431 return result; | 1478 return result; |
| 1432 } | 1479 } |
| 1433 | 1480 |
| 1481 static bool IsEvalOrArguments(Handle<String> string) { |
| 1482 return string.is_identical_to(Factory::eval_symbol()) || |
| 1483 string.is_identical_to(Factory::arguments_symbol()); |
| 1484 } |
| 1434 | 1485 |
| 1435 // If the variable declaration declares exactly one non-const | 1486 // If the variable declaration declares exactly one non-const |
| 1436 // variable, then *var is set to that variable. In all other cases, | 1487 // variable, then *var is set to that variable. In all other cases, |
| 1437 // *var is untouched; in particular, it is the caller's responsibility | 1488 // *var is untouched; in particular, it is the caller's responsibility |
| 1438 // to initialize it properly. This mechanism is used for the parsing | 1489 // to initialize it properly. This mechanism is used for the parsing |
| 1439 // of 'for-in' loops. | 1490 // of 'for-in' loops. |
| 1440 Block* Parser::ParseVariableDeclarations(bool accept_IN, | 1491 Block* Parser::ParseVariableDeclarations(bool accept_IN, |
| 1441 Expression** var, | 1492 Expression** var, |
| 1442 bool* ok) { | 1493 bool* ok) { |
| 1443 // VariableDeclarations :: | 1494 // VariableDeclarations :: |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1472 VariableProxy* last_var = NULL; // the last variable declared | 1523 VariableProxy* last_var = NULL; // the last variable declared |
| 1473 int nvars = 0; // the number of variables declared | 1524 int nvars = 0; // the number of variables declared |
| 1474 do { | 1525 do { |
| 1475 if (fni_ != NULL) fni_->Enter(); | 1526 if (fni_ != NULL) fni_->Enter(); |
| 1476 | 1527 |
| 1477 // Parse variable name. | 1528 // Parse variable name. |
| 1478 if (nvars > 0) Consume(Token::COMMA); | 1529 if (nvars > 0) Consume(Token::COMMA); |
| 1479 Handle<String> name = ParseIdentifier(CHECK_OK); | 1530 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1480 if (fni_ != NULL) fni_->PushVariableName(name); | 1531 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1481 | 1532 |
| 1533 // Strict mode variables may not be named eval or arguments |
| 1534 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { |
| 1535 ReportMessage("strict_var_name", Vector<const char*>::empty()); |
| 1536 *ok = false; |
| 1537 return NULL; |
| 1538 } |
| 1539 |
| 1482 // Declare variable. | 1540 // Declare variable. |
| 1483 // Note that we *always* must treat the initial value via a separate init | 1541 // Note that we *always* must treat the initial value via a separate init |
| 1484 // assignment for variables and constants because the value must be assigned | 1542 // assignment for variables and constants because the value must be assigned |
| 1485 // when the variable is encountered in the source. But the variable/constant | 1543 // when the variable is encountered in the source. But the variable/constant |
| 1486 // is declared (and set to 'undefined') upon entering the function within | 1544 // is declared (and set to 'undefined') upon entering the function within |
| 1487 // which the variable or constant is declared. Only function variables have | 1545 // which the variable or constant is declared. Only function variables have |
| 1488 // an initial value in the declaration (because they are initialized upon | 1546 // an initial value in the declaration (because they are initialized upon |
| 1489 // entering the function). | 1547 // entering the function). |
| 1490 // | 1548 // |
| 1491 // If we have a const declaration, in an inner scope, the proxy is always | 1549 // If we have a const declaration, in an inner scope, the proxy is always |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1832 } | 1890 } |
| 1833 return result; | 1891 return result; |
| 1834 } | 1892 } |
| 1835 | 1893 |
| 1836 | 1894 |
| 1837 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 1895 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 1838 // WithStatement :: | 1896 // WithStatement :: |
| 1839 // 'with' '(' Expression ')' Statement | 1897 // 'with' '(' Expression ')' Statement |
| 1840 | 1898 |
| 1841 Expect(Token::WITH, CHECK_OK); | 1899 Expect(Token::WITH, CHECK_OK); |
| 1900 |
| 1901 if (temp_scope_->StrictMode()) { |
| 1902 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
| 1903 *ok = false; |
| 1904 return NULL; |
| 1905 } |
| 1906 |
| 1842 Expect(Token::LPAREN, CHECK_OK); | 1907 Expect(Token::LPAREN, CHECK_OK); |
| 1843 Expression* expr = ParseExpression(true, CHECK_OK); | 1908 Expression* expr = ParseExpression(true, CHECK_OK); |
| 1844 Expect(Token::RPAREN, CHECK_OK); | 1909 Expect(Token::RPAREN, CHECK_OK); |
| 1845 | 1910 |
| 1846 return WithHelper(expr, labels, false, CHECK_OK); | 1911 return WithHelper(expr, labels, false, CHECK_OK); |
| 1847 } | 1912 } |
| 1848 | 1913 |
| 1849 | 1914 |
| 1850 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 1915 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
| 1851 // CaseClause :: | 1916 // CaseClause :: |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1964 // the jump targets. | 2029 // the jump targets. |
| 1965 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); | 2030 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); |
| 1966 TargetCollector catch_collector(catch_target_list); | 2031 TargetCollector catch_collector(catch_target_list); |
| 1967 bool has_catch = false; | 2032 bool has_catch = false; |
| 1968 if (tok == Token::CATCH) { | 2033 if (tok == Token::CATCH) { |
| 1969 has_catch = true; | 2034 has_catch = true; |
| 1970 Consume(Token::CATCH); | 2035 Consume(Token::CATCH); |
| 1971 | 2036 |
| 1972 Expect(Token::LPAREN, CHECK_OK); | 2037 Expect(Token::LPAREN, CHECK_OK); |
| 1973 Handle<String> name = ParseIdentifier(CHECK_OK); | 2038 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2039 |
| 2040 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { |
| 2041 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); |
| 2042 *ok = false; |
| 2043 return NULL; |
| 2044 } |
| 2045 |
| 1974 Expect(Token::RPAREN, CHECK_OK); | 2046 Expect(Token::RPAREN, CHECK_OK); |
| 1975 | 2047 |
| 1976 if (peek() == Token::LBRACE) { | 2048 if (peek() == Token::LBRACE) { |
| 1977 // Allocate a temporary for holding the finally state while | 2049 // Allocate a temporary for holding the finally state while |
| 1978 // executing the finally block. | 2050 // executing the finally block. |
| 1979 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); | 2051 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); |
| 1980 Literal* name_literal = new Literal(name); | 2052 Literal* name_literal = new Literal(name); |
| 1981 VariableProxy* catch_var_use = new VariableProxy(catch_var); | 2053 VariableProxy* catch_var_use = new VariableProxy(catch_var); |
| 1982 Expression* obj = new CatchExtensionObject(name_literal, catch_var_use); | 2054 Expression* obj = new CatchExtensionObject(name_literal, catch_var_use); |
| 1983 { Target target(&this->target_stack_, &catch_collector); | 2055 { Target target(&this->target_stack_, &catch_collector); |
| (...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3217 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); | 3289 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
| 3218 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 3290 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 3219 scope); | 3291 scope); |
| 3220 TemporaryScope temp_scope(&this->temp_scope_); | 3292 TemporaryScope temp_scope(&this->temp_scope_); |
| 3221 top_scope_->SetScopeName(name); | 3293 top_scope_->SetScopeName(name); |
| 3222 | 3294 |
| 3223 // FormalParameterList :: | 3295 // FormalParameterList :: |
| 3224 // '(' (Identifier)*[','] ')' | 3296 // '(' (Identifier)*[','] ')' |
| 3225 Expect(Token::LPAREN, CHECK_OK); | 3297 Expect(Token::LPAREN, CHECK_OK); |
| 3226 int start_pos = scanner().location().beg_pos; | 3298 int start_pos = scanner().location().beg_pos; |
| 3299 |
| 3227 bool done = (peek() == Token::RPAREN); | 3300 bool done = (peek() == Token::RPAREN); |
| 3228 while (!done) { | 3301 while (!done) { |
| 3229 Handle<String> param_name = ParseIdentifier(CHECK_OK); | 3302 Handle<String> param_name = ParseIdentifier(CHECK_OK); |
| 3230 top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, | 3303 Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR); |
| 3231 Variable::VAR)); | 3304 top_scope_->AddParameter(parameter); |
| 3232 num_parameters++; | 3305 num_parameters++; |
| 3233 done = (peek() == Token::RPAREN); | 3306 done = (peek() == Token::RPAREN); |
| 3234 if (!done) Expect(Token::COMMA, CHECK_OK); | 3307 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3235 } | 3308 } |
| 3236 Expect(Token::RPAREN, CHECK_OK); | 3309 Expect(Token::RPAREN, CHECK_OK); |
| 3237 | 3310 |
| 3238 Expect(Token::LBRACE, CHECK_OK); | 3311 Expect(Token::LBRACE, CHECK_OK); |
| 3239 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); | 3312 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); |
| 3240 | 3313 |
| 3241 // If we have a named function expression, we add a local variable | 3314 // If we have a named function expression, we add a local variable |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3293 materialized_literal_count = temp_scope.materialized_literal_count(); | 3366 materialized_literal_count = temp_scope.materialized_literal_count(); |
| 3294 expected_property_count = temp_scope.expected_property_count(); | 3367 expected_property_count = temp_scope.expected_property_count(); |
| 3295 only_simple_this_property_assignments = | 3368 only_simple_this_property_assignments = |
| 3296 temp_scope.only_simple_this_property_assignments(); | 3369 temp_scope.only_simple_this_property_assignments(); |
| 3297 this_property_assignments = temp_scope.this_property_assignments(); | 3370 this_property_assignments = temp_scope.this_property_assignments(); |
| 3298 | 3371 |
| 3299 Expect(Token::RBRACE, CHECK_OK); | 3372 Expect(Token::RBRACE, CHECK_OK); |
| 3300 end_pos = scanner().location().end_pos; | 3373 end_pos = scanner().location().end_pos; |
| 3301 } | 3374 } |
| 3302 | 3375 |
| 3376 // Validate strict mode. |
| 3377 if (temp_scope_->StrictMode()) { |
| 3378 if (IsEvalOrArguments(name)) { |
| 3379 int position = function_token_position != RelocInfo::kNoPosition |
| 3380 ? function_token_position |
| 3381 : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 3382 ReportMessageAt(Scanner::Location(position, start_pos), |
| 3383 "strict_function_name", Vector<const char*>::empty()); |
| 3384 *ok = false; |
| 3385 return NULL; |
| 3386 } |
| 3387 // TODO(mmaly): Check for octal escape sequence here. |
| 3388 } |
| 3389 |
| 3303 FunctionLiteral* function_literal = | 3390 FunctionLiteral* function_literal = |
| 3304 new FunctionLiteral(name, | 3391 new FunctionLiteral(name, |
| 3305 top_scope_, | 3392 top_scope_, |
| 3306 body, | 3393 body, |
| 3307 materialized_literal_count, | 3394 materialized_literal_count, |
| 3308 expected_property_count, | 3395 expected_property_count, |
| 3309 only_simple_this_property_assignments, | 3396 only_simple_this_property_assignments, |
| 3310 this_property_assignments, | 3397 this_property_assignments, |
| 3311 num_parameters, | 3398 num_parameters, |
| 3312 start_pos, | 3399 start_pos, |
| 3313 end_pos, | 3400 end_pos, |
| 3314 function_name->length() > 0, | 3401 function_name->length() > 0, |
| 3315 temp_scope.ContainsLoops()); | 3402 temp_scope.ContainsLoops(), |
| 3403 temp_scope.StrictMode()); |
| 3316 function_literal->set_function_token_position(function_token_position); | 3404 function_literal->set_function_token_position(function_token_position); |
| 3317 | 3405 |
| 3318 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); | 3406 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); |
| 3319 return function_literal; | 3407 return function_literal; |
| 3320 } | 3408 } |
| 3321 } | 3409 } |
| 3322 | 3410 |
| 3323 | 3411 |
| 3324 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3412 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3325 // CallRuntime :: | 3413 // CallRuntime :: |
| (...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4730 Handle<String> source = Handle<String>(String::cast(script->source())); | 4818 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 4731 result = parser.ParseProgram(source, info->is_global()); | 4819 result = parser.ParseProgram(source, info->is_global()); |
| 4732 } | 4820 } |
| 4733 } | 4821 } |
| 4734 | 4822 |
| 4735 info->SetFunction(result); | 4823 info->SetFunction(result); |
| 4736 return (result != NULL); | 4824 return (result != NULL); |
| 4737 } | 4825 } |
| 4738 | 4826 |
| 4739 } } // namespace v8::internal | 4827 } } // namespace v8::internal |
| OLD | NEW |