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