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 | |
| 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_ : false; | |
|
Lasse Reichstein
2011/01/18 13:40:59
Can be written
(parent_ != NULL) && parent_->str
Martin Maly
2011/01/18 16:46:38
Done.
| |
| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 top_scope_, | 670 top_scope_, |
| 662 body, | 671 body, |
| 663 temp_scope.materialized_literal_count(), | 672 temp_scope.materialized_literal_count(), |
| 664 temp_scope.expected_property_count(), | 673 temp_scope.expected_property_count(), |
| 665 temp_scope.only_simple_this_property_assignments(), | 674 temp_scope.only_simple_this_property_assignments(), |
| 666 temp_scope.this_property_assignments(), | 675 temp_scope.this_property_assignments(), |
| 667 0, | 676 0, |
| 668 0, | 677 0, |
| 669 source->length(), | 678 source->length(), |
| 670 false, | 679 false, |
| 671 temp_scope.ContainsLoops()); | 680 temp_scope.ContainsLoops(), |
| 681 temp_scope.StrictMode()); | |
| 672 } else if (stack_overflow_) { | 682 } else if (stack_overflow_) { |
| 673 Top::StackOverflow(); | 683 Top::StackOverflow(); |
| 674 } | 684 } |
| 675 } | 685 } |
| 676 | 686 |
| 677 // Make sure the target stack is empty. | 687 // Make sure the target stack is empty. |
| 678 ASSERT(target_stack_ == NULL); | 688 ASSERT(target_stack_ == NULL); |
| 679 | 689 |
| 680 // If there was a syntax error we have to get rid of the AST | 690 // 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. | 691 // 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 | 1061 |
| 1052 // Allocate a target stack to use for this set of source | 1062 // Allocate a target stack to use for this set of source |
| 1053 // elements. This way, all scripts and functions get their own | 1063 // elements. This way, all scripts and functions get their own |
| 1054 // target stack thus avoiding illegal breaks and continues across | 1064 // target stack thus avoiding illegal breaks and continues across |
| 1055 // functions. | 1065 // functions. |
| 1056 TargetScope scope(&this->target_stack_); | 1066 TargetScope scope(&this->target_stack_); |
| 1057 | 1067 |
| 1058 ASSERT(processor != NULL); | 1068 ASSERT(processor != NULL); |
| 1059 InitializationBlockFinder block_finder; | 1069 InitializationBlockFinder block_finder; |
| 1060 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; | 1070 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; |
| 1071 bool directive_prologue = true; // Parsing directive prologue. | |
| 1072 | |
| 1061 while (peek() != end_token) { | 1073 while (peek() != end_token) { |
| 1074 if (directive_prologue && peek() != Token::STRING) { | |
| 1075 directive_prologue = false; | |
| 1076 } | |
| 1077 | |
| 1078 Scanner::Location token_loc = scanner().peek_location(); | |
| 1062 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1079 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 1063 if (stat == NULL || stat->IsEmpty()) continue; | 1080 |
| 1081 if (stat == NULL || stat->IsEmpty()) { | |
| 1082 directive_prologue = false; // End of directive prologue. | |
| 1083 continue; | |
| 1084 } | |
| 1085 | |
| 1086 if (directive_prologue) { | |
| 1087 // A shot at a directive. | |
| 1088 ExpressionStatement *e_stat; | |
| 1089 Literal *literal; | |
| 1090 // Still processing directive prologue? | |
| 1091 if ((e_stat = stat->AsExpressionStatement()) != NULL && | |
| 1092 (literal = e_stat->expression()->AsLiteral()) != NULL && | |
| 1093 literal->handle()->IsString()) { | |
| 1094 Handle<String> directive = Handle<String>::cast(literal->handle()); | |
| 1095 | |
| 1096 // Check "use strict" directive (ES5 14.1). | |
| 1097 if (!temp_scope_->StrictMode() && | |
| 1098 directive->Equals(Heap::use_strict()) && | |
| 1099 token_loc.end_pos - token_loc.beg_pos == | |
| 1100 Heap::use_strict()->length() + 2) { | |
| 1101 temp_scope_->EnableStrictMode(); | |
|
Lasse Reichstein
2011/01/18 13:40:59
You can set directive_prologue to false here, sinc
Martin Maly
2011/01/18 16:46:38
Done.
| |
| 1102 } | |
| 1103 } else { | |
| 1104 // End of the directive prologue. | |
| 1105 directive_prologue = false; | |
| 1106 } | |
| 1107 } | |
| 1108 | |
| 1064 // We find and mark the initialization blocks on top level code only. | 1109 // We find and mark the initialization blocks on top level code only. |
| 1065 // This is because the optimization prevents reuse of the map transitions, | 1110 // 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. | 1111 // so it should be used only for code that will only be run once. |
| 1067 if (top_scope_->is_global_scope()) { | 1112 if (top_scope_->is_global_scope()) { |
| 1068 block_finder.Update(stat); | 1113 block_finder.Update(stat); |
| 1069 } | 1114 } |
| 1070 // Find and mark all assignments to named properties in this (this.x =) | 1115 // Find and mark all assignments to named properties in this (this.x =) |
| 1071 if (top_scope_->is_function_scope()) { | 1116 if (top_scope_->is_function_scope()) { |
| 1072 this_property_assignment_finder.Update(top_scope_, stat); | 1117 this_property_assignment_finder.Update(top_scope_, stat); |
| 1073 } | 1118 } |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1407 Block* Parser::ParseVariableStatement(bool* ok) { | 1452 Block* Parser::ParseVariableStatement(bool* ok) { |
| 1408 // VariableStatement :: | 1453 // VariableStatement :: |
| 1409 // VariableDeclarations ';' | 1454 // VariableDeclarations ';' |
| 1410 | 1455 |
| 1411 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature | 1456 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature |
| 1412 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK); | 1457 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK); |
| 1413 ExpectSemicolon(CHECK_OK); | 1458 ExpectSemicolon(CHECK_OK); |
| 1414 return result; | 1459 return result; |
| 1415 } | 1460 } |
| 1416 | 1461 |
| 1462 static bool IsEvalOrArguments(Handle<String> string) { | |
| 1463 return string.is_identical_to(Factory::eval_symbol()) || | |
| 1464 string.is_identical_to(Factory::arguments_symbol()); | |
| 1465 } | |
| 1417 | 1466 |
| 1418 // If the variable declaration declares exactly one non-const | 1467 // If the variable declaration declares exactly one non-const |
| 1419 // variable, then *var is set to that variable. In all other cases, | 1468 // variable, then *var is set to that variable. In all other cases, |
| 1420 // *var is untouched; in particular, it is the caller's responsibility | 1469 // *var is untouched; in particular, it is the caller's responsibility |
| 1421 // to initialize it properly. This mechanism is used for the parsing | 1470 // to initialize it properly. This mechanism is used for the parsing |
| 1422 // of 'for-in' loops. | 1471 // of 'for-in' loops. |
| 1423 Block* Parser::ParseVariableDeclarations(bool accept_IN, | 1472 Block* Parser::ParseVariableDeclarations(bool accept_IN, |
| 1424 Expression** var, | 1473 Expression** var, |
| 1425 bool* ok) { | 1474 bool* ok) { |
| 1426 // VariableDeclarations :: | 1475 // VariableDeclarations :: |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1455 VariableProxy* last_var = NULL; // the last variable declared | 1504 VariableProxy* last_var = NULL; // the last variable declared |
| 1456 int nvars = 0; // the number of variables declared | 1505 int nvars = 0; // the number of variables declared |
| 1457 do { | 1506 do { |
| 1458 if (fni_ != NULL) fni_->Enter(); | 1507 if (fni_ != NULL) fni_->Enter(); |
| 1459 | 1508 |
| 1460 // Parse variable name. | 1509 // Parse variable name. |
| 1461 if (nvars > 0) Consume(Token::COMMA); | 1510 if (nvars > 0) Consume(Token::COMMA); |
| 1462 Handle<String> name = ParseIdentifier(CHECK_OK); | 1511 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1463 if (fni_ != NULL) fni_->PushVariableName(name); | 1512 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1464 | 1513 |
| 1514 // Strict mode variables may not be named eval or arguments | |
| 1515 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { | |
| 1516 ReportMessage("strict_var_name", Vector<const char*>::empty()); | |
| 1517 *ok = false; | |
| 1518 return NULL; | |
| 1519 } | |
| 1520 | |
| 1465 // Declare variable. | 1521 // Declare variable. |
| 1466 // Note that we *always* must treat the initial value via a separate init | 1522 // 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 | 1523 // assignment for variables and constants because the value must be assigned |
| 1468 // when the variable is encountered in the source. But the variable/constant | 1524 // when the variable is encountered in the source. But the variable/constant |
| 1469 // is declared (and set to 'undefined') upon entering the function within | 1525 // is declared (and set to 'undefined') upon entering the function within |
| 1470 // which the variable or constant is declared. Only function variables have | 1526 // which the variable or constant is declared. Only function variables have |
| 1471 // an initial value in the declaration (because they are initialized upon | 1527 // an initial value in the declaration (because they are initialized upon |
| 1472 // entering the function). | 1528 // entering the function). |
| 1473 // | 1529 // |
| 1474 // If we have a const declaration, in an inner scope, the proxy is always | 1530 // 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 } | 1863 } |
| 1808 return result; | 1864 return result; |
| 1809 } | 1865 } |
| 1810 | 1866 |
| 1811 | 1867 |
| 1812 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 1868 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 1813 // WithStatement :: | 1869 // WithStatement :: |
| 1814 // 'with' '(' Expression ')' Statement | 1870 // 'with' '(' Expression ')' Statement |
| 1815 | 1871 |
| 1816 Expect(Token::WITH, CHECK_OK); | 1872 Expect(Token::WITH, CHECK_OK); |
| 1873 | |
| 1874 if (temp_scope_->StrictMode()) { | |
| 1875 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | |
| 1876 *ok = false; | |
| 1877 return NULL; | |
| 1878 } | |
| 1879 | |
| 1817 Expect(Token::LPAREN, CHECK_OK); | 1880 Expect(Token::LPAREN, CHECK_OK); |
| 1818 Expression* expr = ParseExpression(true, CHECK_OK); | 1881 Expression* expr = ParseExpression(true, CHECK_OK); |
| 1819 Expect(Token::RPAREN, CHECK_OK); | 1882 Expect(Token::RPAREN, CHECK_OK); |
| 1820 | 1883 |
| 1821 return WithHelper(expr, labels, false, CHECK_OK); | 1884 return WithHelper(expr, labels, false, CHECK_OK); |
| 1822 } | 1885 } |
| 1823 | 1886 |
| 1824 | 1887 |
| 1825 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 1888 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
| 1826 // CaseClause :: | 1889 // CaseClause :: |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1939 // the jump targets. | 2002 // the jump targets. |
| 1940 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); | 2003 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); |
| 1941 TargetCollector catch_collector(catch_target_list); | 2004 TargetCollector catch_collector(catch_target_list); |
| 1942 bool has_catch = false; | 2005 bool has_catch = false; |
| 1943 if (tok == Token::CATCH) { | 2006 if (tok == Token::CATCH) { |
| 1944 has_catch = true; | 2007 has_catch = true; |
| 1945 Consume(Token::CATCH); | 2008 Consume(Token::CATCH); |
| 1946 | 2009 |
| 1947 Expect(Token::LPAREN, CHECK_OK); | 2010 Expect(Token::LPAREN, CHECK_OK); |
| 1948 Handle<String> name = ParseIdentifier(CHECK_OK); | 2011 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2012 | |
| 2013 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { | |
| 2014 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | |
| 2015 *ok = false; | |
| 2016 return NULL; | |
| 2017 } | |
| 2018 | |
| 1949 Expect(Token::RPAREN, CHECK_OK); | 2019 Expect(Token::RPAREN, CHECK_OK); |
| 1950 | 2020 |
| 1951 if (peek() == Token::LBRACE) { | 2021 if (peek() == Token::LBRACE) { |
| 1952 // Allocate a temporary for holding the finally state while | 2022 // Allocate a temporary for holding the finally state while |
| 1953 // executing the finally block. | 2023 // executing the finally block. |
| 1954 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); | 2024 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); |
| 1955 Literal* name_literal = new Literal(name); | 2025 Literal* name_literal = new Literal(name); |
| 1956 VariableProxy* catch_var_use = new VariableProxy(catch_var); | 2026 VariableProxy* catch_var_use = new VariableProxy(catch_var); |
| 1957 Expression* obj = new CatchExtensionObject(name_literal, catch_var_use); | 2027 Expression* obj = new CatchExtensionObject(name_literal, catch_var_use); |
| 1958 { Target target(&this->target_stack_, &catch_collector); | 2028 { 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()); | 3255 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
| 3186 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 3256 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 3187 scope); | 3257 scope); |
| 3188 TemporaryScope temp_scope(&this->temp_scope_); | 3258 TemporaryScope temp_scope(&this->temp_scope_); |
| 3189 top_scope_->SetScopeName(name); | 3259 top_scope_->SetScopeName(name); |
| 3190 | 3260 |
| 3191 // FormalParameterList :: | 3261 // FormalParameterList :: |
| 3192 // '(' (Identifier)*[','] ')' | 3262 // '(' (Identifier)*[','] ')' |
| 3193 Expect(Token::LPAREN, CHECK_OK); | 3263 Expect(Token::LPAREN, CHECK_OK); |
| 3194 int start_pos = scanner().location().beg_pos; | 3264 int start_pos = scanner().location().beg_pos; |
| 3265 Scanner::Location eval_loc(RelocInfo::kNoPosition, RelocInfo::kNoPosition); | |
| 3266 Scanner::Location dupe_loc(RelocInfo::kNoPosition, RelocInfo::kNoPosition); | |
| 3267 | |
| 3195 bool done = (peek() == Token::RPAREN); | 3268 bool done = (peek() == Token::RPAREN); |
| 3196 while (!done) { | 3269 while (!done) { |
| 3197 Handle<String> param_name = ParseIdentifier(CHECK_OK); | 3270 Handle<String> param_name = ParseIdentifier(CHECK_OK); |
| 3198 top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, | 3271 Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR); |
| 3199 Variable::VAR)); | 3272 |
| 3273 // Store locations for possible future error reports. | |
| 3274 if (eval_loc.beg_pos == RelocInfo::kNoPosition && | |
| 3275 IsEvalOrArguments(param_name)) { | |
| 3276 // Store location for later | |
| 3277 eval_loc = scanner().location(); | |
| 3278 } | |
| 3279 if (dupe_loc.beg_pos == RelocInfo::kNoPosition && | |
| 3280 top_scope_->IsParameterDeclared(param_name)) { | |
| 3281 // Store location for later | |
| 3282 dupe_loc = scanner().location(); | |
| 3283 } | |
| 3284 | |
| 3285 top_scope_->AddParameter(parameter); | |
| 3200 num_parameters++; | 3286 num_parameters++; |
| 3201 done = (peek() == Token::RPAREN); | 3287 done = (peek() == Token::RPAREN); |
| 3202 if (!done) Expect(Token::COMMA, CHECK_OK); | 3288 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3203 } | 3289 } |
| 3204 Expect(Token::RPAREN, CHECK_OK); | 3290 Expect(Token::RPAREN, CHECK_OK); |
| 3205 | 3291 |
| 3206 Expect(Token::LBRACE, CHECK_OK); | 3292 Expect(Token::LBRACE, CHECK_OK); |
| 3207 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); | 3293 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); |
| 3208 | 3294 |
| 3209 // If we have a named function expression, we add a local variable | 3295 // 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(); | 3344 materialized_literal_count = temp_scope.materialized_literal_count(); |
| 3259 expected_property_count = temp_scope.expected_property_count(); | 3345 expected_property_count = temp_scope.expected_property_count(); |
| 3260 only_simple_this_property_assignments = | 3346 only_simple_this_property_assignments = |
| 3261 temp_scope.only_simple_this_property_assignments(); | 3347 temp_scope.only_simple_this_property_assignments(); |
| 3262 this_property_assignments = temp_scope.this_property_assignments(); | 3348 this_property_assignments = temp_scope.this_property_assignments(); |
| 3263 | 3349 |
| 3264 Expect(Token::RBRACE, CHECK_OK); | 3350 Expect(Token::RBRACE, CHECK_OK); |
| 3265 end_pos = scanner().location().end_pos; | 3351 end_pos = scanner().location().end_pos; |
| 3266 } | 3352 } |
| 3267 | 3353 |
| 3354 // Validate strict mode. | |
| 3355 if (temp_scope_->StrictMode()) { | |
| 3356 if (IsEvalOrArguments(name)) { | |
| 3357 int position = function_token_position != RelocInfo::kNoPosition | |
| 3358 ? function_token_position | |
| 3359 : (start_pos > 0 ? start_pos - 1 : start_pos); | |
| 3360 ReportMessageAt(Scanner::Location(position, start_pos), | |
| 3361 "strict_function_name", Vector<const char*>::empty()); | |
| 3362 *ok = false; | |
| 3363 return NULL; | |
| 3364 } | |
| 3365 if (eval_loc.beg_pos != RelocInfo::kNoPosition) { | |
| 3366 ReportMessageAt(eval_loc, "strict_param_name", | |
| 3367 Vector<const char*>::empty()); | |
| 3368 *ok = false; | |
| 3369 return NULL; | |
| 3370 } | |
| 3371 if (dupe_loc.beg_pos != RelocInfo::kNoPosition) { | |
| 3372 ReportMessageAt(dupe_loc, "strict_param_dupe", | |
| 3373 Vector<const char*>::empty()); | |
| 3374 *ok = false; | |
| 3375 return NULL; | |
| 3376 } | |
| 3377 // TODO(mmaly): Check for octal escape sequence here. | |
| 3378 } | |
| 3379 | |
| 3268 FunctionLiteral* function_literal = | 3380 FunctionLiteral* function_literal = |
| 3269 new FunctionLiteral(name, | 3381 new FunctionLiteral(name, |
| 3270 top_scope_, | 3382 top_scope_, |
| 3271 body, | 3383 body, |
| 3272 materialized_literal_count, | 3384 materialized_literal_count, |
| 3273 expected_property_count, | 3385 expected_property_count, |
| 3274 only_simple_this_property_assignments, | 3386 only_simple_this_property_assignments, |
| 3275 this_property_assignments, | 3387 this_property_assignments, |
| 3276 num_parameters, | 3388 num_parameters, |
| 3277 start_pos, | 3389 start_pos, |
| 3278 end_pos, | 3390 end_pos, |
| 3279 function_name->length() > 0, | 3391 function_name->length() > 0, |
| 3280 temp_scope.ContainsLoops()); | 3392 temp_scope.ContainsLoops(), |
| 3393 temp_scope.StrictMode()); | |
| 3281 function_literal->set_function_token_position(function_token_position); | 3394 function_literal->set_function_token_position(function_token_position); |
| 3282 | 3395 |
| 3283 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); | 3396 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); |
| 3284 return function_literal; | 3397 return function_literal; |
| 3285 } | 3398 } |
| 3286 } | 3399 } |
| 3287 | 3400 |
| 3288 | 3401 |
| 3289 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3402 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3290 // CallRuntime :: | 3403 // CallRuntime :: |
| (...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4695 Handle<String> source = Handle<String>(String::cast(script->source())); | 4808 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 4696 result = parser.ParseProgram(source, info->is_global()); | 4809 result = parser.ParseProgram(source, info->is_global()); |
| 4697 } | 4810 } |
| 4698 } | 4811 } |
| 4699 | 4812 |
| 4700 info->SetFunction(result); | 4813 info->SetFunction(result); |
| 4701 return (result != NULL); | 4814 return (result != NULL); |
| 4702 } | 4815 } |
| 4703 | 4816 |
| 4704 } } // namespace v8::internal | 4817 } } // namespace v8::internal |
| OLD | NEW |