Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(417)

Side by Side Diff: src/parser.cc

Issue 6144005: Early draft of strict mode (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Lasse's code review feedback + flag Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/messages.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/messages.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698