OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1338 stmt = ParseExpressionOrLabelledStatement(labels, ok); | 1338 stmt = ParseExpressionOrLabelledStatement(labels, ok); |
1339 } | 1339 } |
1340 | 1340 |
1341 // Store the source position of the statement | 1341 // Store the source position of the statement |
1342 if (stmt != NULL) stmt->set_statement_pos(statement_pos); | 1342 if (stmt != NULL) stmt->set_statement_pos(statement_pos); |
1343 return stmt; | 1343 return stmt; |
1344 } | 1344 } |
1345 | 1345 |
1346 | 1346 |
1347 VariableProxy* Parser::Declare(Handle<String> name, | 1347 VariableProxy* Parser::Declare(Handle<String> name, |
1348 Variable::Mode mode, | 1348 VariableMode mode, |
1349 FunctionLiteral* fun, | 1349 FunctionLiteral* fun, |
1350 bool resolve, | 1350 bool resolve, |
1351 bool* ok) { | 1351 bool* ok) { |
1352 Variable* var = NULL; | 1352 Variable* var = NULL; |
1353 // If we are inside a function, a declaration of a var/const variable is a | 1353 // If we are inside a function, a declaration of a var/const variable is a |
1354 // truly local variable, and the scope of the variable is always the function | 1354 // truly local variable, and the scope of the variable is always the function |
1355 // scope. | 1355 // scope. |
1356 | 1356 |
1357 // If a function scope exists, then we can statically declare this | 1357 // If a function scope exists, then we can statically declare this |
1358 // variable and also set its mode. In any case, a Declaration node | 1358 // variable and also set its mode. In any case, a Declaration node |
1359 // will be added to the scope so that the declaration can be added | 1359 // will be added to the scope so that the declaration can be added |
1360 // to the corresponding activation frame at runtime if necessary. | 1360 // to the corresponding activation frame at runtime if necessary. |
1361 // For instance declarations inside an eval scope need to be added | 1361 // For instance declarations inside an eval scope need to be added |
1362 // to the calling function context. | 1362 // to the calling function context. |
1363 // Similarly, strict mode eval scope does not leak variable declarations to | 1363 // Similarly, strict mode eval scope does not leak variable declarations to |
1364 // the caller's scope so we declare all locals, too. | 1364 // the caller's scope so we declare all locals, too. |
1365 | 1365 |
1366 Scope* declaration_scope = mode == Variable::LET ? top_scope_ | 1366 Scope* declaration_scope = mode == LET ? top_scope_ |
1367 : top_scope_->DeclarationScope(); | 1367 : top_scope_->DeclarationScope(); |
1368 if (declaration_scope->is_function_scope() || | 1368 if (declaration_scope->is_function_scope() || |
1369 declaration_scope->is_strict_mode_eval_scope() || | 1369 declaration_scope->is_strict_mode_eval_scope() || |
1370 declaration_scope->is_block_scope()) { | 1370 declaration_scope->is_block_scope()) { |
1371 // Declare the variable in the function scope. | 1371 // Declare the variable in the function scope. |
1372 var = declaration_scope->LocalLookup(name); | 1372 var = declaration_scope->LocalLookup(name); |
1373 if (var == NULL) { | 1373 if (var == NULL) { |
1374 // Declare the name. | 1374 // Declare the name. |
1375 var = declaration_scope->DeclareLocal(name, mode); | 1375 var = declaration_scope->DeclareLocal(name, mode); |
1376 } else { | 1376 } else { |
1377 // The name was declared in this scope before; check for conflicting | 1377 // The name was declared in this scope before; check for conflicting |
1378 // re-declarations. We have a conflict if either of the declarations is | 1378 // re-declarations. We have a conflict if either of the declarations is |
1379 // not a var. There is similar code in runtime.cc in the Declare | 1379 // not a var. There is similar code in runtime.cc in the Declare |
1380 // functions. The function CheckNonConflictingScope checks for conflicting | 1380 // functions. The function CheckNonConflictingScope checks for conflicting |
1381 // var and let bindings from different scopes whereas this is a check for | 1381 // var and let bindings from different scopes whereas this is a check for |
1382 // conflicting declarations within the same scope. This check also covers | 1382 // conflicting declarations within the same scope. This check also covers |
1383 // | 1383 // |
1384 // function () { let x; { var x; } } | 1384 // function () { let x; { var x; } } |
1385 // | 1385 // |
1386 // because the var declaration is hoisted to the function scope where 'x' | 1386 // because the var declaration is hoisted to the function scope where 'x' |
1387 // is already bound. | 1387 // is already bound. |
1388 if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) { | 1388 if ((mode != VAR) || (var->mode() != VAR)) { |
1389 // We only have vars, consts and lets in declarations. | 1389 // We only have vars, consts and lets in declarations. |
1390 ASSERT(var->mode() == Variable::VAR || | 1390 ASSERT(var->mode() == VAR || |
1391 var->mode() == Variable::CONST || | 1391 var->mode() == CONST || |
1392 var->mode() == Variable::LET); | 1392 var->mode() == LET); |
1393 if (harmony_block_scoping_) { | 1393 if (harmony_block_scoping_) { |
1394 // In harmony mode we treat re-declarations as early errors. See | 1394 // In harmony mode we treat re-declarations as early errors. See |
1395 // ES5 16 for a definition of early errors. | 1395 // ES5 16 for a definition of early errors. |
1396 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 1396 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
1397 const char* elms[2] = { "Variable", *c_string }; | 1397 const char* elms[2] = { "Variable", *c_string }; |
1398 Vector<const char*> args(elms, 2); | 1398 Vector<const char*> args(elms, 2); |
1399 ReportMessage("redeclaration", args); | 1399 ReportMessage("redeclaration", args); |
1400 *ok = false; | 1400 *ok = false; |
1401 return NULL; | 1401 return NULL; |
1402 } | 1402 } |
1403 const char* type = (var->mode() == Variable::VAR) ? "var" : | 1403 const char* type = (var->mode() == VAR) ? "var" : |
1404 (var->mode() == Variable::CONST) ? "const" : "let"; | 1404 (var->mode() == CONST) ? "const" : "let"; |
1405 Handle<String> type_string = | 1405 Handle<String> type_string = |
1406 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); | 1406 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); |
1407 Expression* expression = | 1407 Expression* expression = |
1408 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), | 1408 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), |
1409 type_string, name); | 1409 type_string, name); |
1410 declaration_scope->SetIllegalRedeclaration(expression); | 1410 declaration_scope->SetIllegalRedeclaration(expression); |
1411 } | 1411 } |
1412 } | 1412 } |
1413 } | 1413 } |
1414 | 1414 |
(...skipping 12 matching lines...) Expand all Loading... | |
1427 // same variable if it is declared several times. This is not a | 1427 // same variable if it is declared several times. This is not a |
1428 // semantic issue as long as we keep the source order, but it may be | 1428 // semantic issue as long as we keep the source order, but it may be |
1429 // a performance issue since it may lead to repeated | 1429 // a performance issue since it may lead to repeated |
1430 // Runtime::DeclareContextSlot() calls. | 1430 // Runtime::DeclareContextSlot() calls. |
1431 VariableProxy* proxy = declaration_scope->NewUnresolved( | 1431 VariableProxy* proxy = declaration_scope->NewUnresolved( |
1432 name, false, scanner().location().beg_pos); | 1432 name, false, scanner().location().beg_pos); |
1433 declaration_scope->AddDeclaration( | 1433 declaration_scope->AddDeclaration( |
1434 new(zone()) Declaration(proxy, mode, fun, top_scope_)); | 1434 new(zone()) Declaration(proxy, mode, fun, top_scope_)); |
1435 | 1435 |
1436 // For global const variables we bind the proxy to a variable. | 1436 // For global const variables we bind the proxy to a variable. |
1437 if (mode == Variable::CONST && declaration_scope->is_global_scope()) { | 1437 if (mode == CONST && declaration_scope->is_global_scope()) { |
1438 ASSERT(resolve); // should be set by all callers | 1438 ASSERT(resolve); // should be set by all callers |
1439 Variable::Kind kind = Variable::NORMAL; | 1439 Variable::Kind kind = Variable::NORMAL; |
1440 var = new(zone()) Variable(declaration_scope, | 1440 var = new(zone()) Variable(declaration_scope, name, CONST, true, kind); |
1441 name, | |
1442 Variable::CONST, | |
1443 true, | |
1444 kind); | |
1445 } | 1441 } |
1446 | 1442 |
1447 // If requested and we have a local variable, bind the proxy to the variable | 1443 // If requested and we have a local variable, bind the proxy to the variable |
1448 // at parse-time. This is used for functions (and consts) declared inside | 1444 // at parse-time. This is used for functions (and consts) declared inside |
1449 // statements: the corresponding function (or const) variable must be in the | 1445 // statements: the corresponding function (or const) variable must be in the |
1450 // function scope and not a statement-local scope, e.g. as provided with a | 1446 // function scope and not a statement-local scope, e.g. as provided with a |
1451 // 'with' statement: | 1447 // 'with' statement: |
1452 // | 1448 // |
1453 // with (obj) { | 1449 // with (obj) { |
1454 // function f() {} | 1450 // function f() {} |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1517 // Copy the function data to the shared function info. | 1513 // Copy the function data to the shared function info. |
1518 shared->set_function_data(fun->shared()->function_data()); | 1514 shared->set_function_data(fun->shared()->function_data()); |
1519 int parameters = fun->shared()->formal_parameter_count(); | 1515 int parameters = fun->shared()->formal_parameter_count(); |
1520 shared->set_formal_parameter_count(parameters); | 1516 shared->set_formal_parameter_count(parameters); |
1521 | 1517 |
1522 // TODO(1240846): It's weird that native function declarations are | 1518 // TODO(1240846): It's weird that native function declarations are |
1523 // introduced dynamically when we meet their declarations, whereas | 1519 // introduced dynamically when we meet their declarations, whereas |
1524 // other functions are setup when entering the surrounding scope. | 1520 // other functions are setup when entering the surrounding scope. |
1525 SharedFunctionInfoLiteral* lit = | 1521 SharedFunctionInfoLiteral* lit = |
1526 new(zone()) SharedFunctionInfoLiteral(isolate(), shared); | 1522 new(zone()) SharedFunctionInfoLiteral(isolate(), shared); |
1527 VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK); | 1523 VariableProxy* var = Declare(name, VAR, NULL, true, CHECK_OK); |
1528 return new(zone()) ExpressionStatement(new(zone()) Assignment( | 1524 return new(zone()) ExpressionStatement(new(zone()) Assignment( |
1529 isolate(), Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); | 1525 isolate(), Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); |
1530 } | 1526 } |
1531 | 1527 |
1532 | 1528 |
1533 Statement* Parser::ParseFunctionDeclaration(bool* ok) { | 1529 Statement* Parser::ParseFunctionDeclaration(bool* ok) { |
1534 // FunctionDeclaration :: | 1530 // FunctionDeclaration :: |
1535 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1531 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
1536 Expect(Token::FUNCTION, CHECK_OK); | 1532 Expect(Token::FUNCTION, CHECK_OK); |
1537 int function_token_position = scanner().location().beg_pos; | 1533 int function_token_position = scanner().location().beg_pos; |
1538 bool is_strict_reserved = false; | 1534 bool is_strict_reserved = false; |
1539 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1535 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
1540 &is_strict_reserved, CHECK_OK); | 1536 &is_strict_reserved, CHECK_OK); |
1541 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1537 FunctionLiteral* fun = ParseFunctionLiteral(name, |
1542 is_strict_reserved, | 1538 is_strict_reserved, |
1543 function_token_position, | 1539 function_token_position, |
1544 FunctionLiteral::DECLARATION, | 1540 FunctionLiteral::DECLARATION, |
1545 CHECK_OK); | 1541 CHECK_OK); |
1546 // Even if we're not at the top-level of the global or a function | 1542 // Even if we're not at the top-level of the global or a function |
1547 // scope, we treat is as such and introduce the function with it's | 1543 // scope, we treat is as such and introduce the function with it's |
1548 // initial value upon entering the corresponding scope. | 1544 // initial value upon entering the corresponding scope. |
1549 Variable::Mode mode = harmony_block_scoping_ ? Variable::LET : Variable::VAR; | 1545 VariableMode mode = harmony_block_scoping_ ? LET : VAR; |
1550 Declare(name, mode, fun, true, CHECK_OK); | 1546 Declare(name, mode, fun, true, CHECK_OK); |
1551 return EmptyStatement(); | 1547 return EmptyStatement(); |
1552 } | 1548 } |
1553 | 1549 |
1554 | 1550 |
1555 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1551 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
1556 if (harmony_block_scoping_) return ParseScopedBlock(labels, ok); | 1552 if (harmony_block_scoping_) return ParseScopedBlock(labels, ok); |
1557 | 1553 |
1558 // Block :: | 1554 // Block :: |
1559 // '{' Statement* '}' | 1555 // '{' Statement* '}' |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1644 // variable, then *var is set to that variable. In all other cases, | 1640 // variable, then *var is set to that variable. In all other cases, |
1645 // *var is untouched; in particular, it is the caller's responsibility | 1641 // *var is untouched; in particular, it is the caller's responsibility |
1646 // to initialize it properly. This mechanism is used for the parsing | 1642 // to initialize it properly. This mechanism is used for the parsing |
1647 // of 'for-in' loops. | 1643 // of 'for-in' loops. |
1648 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context, | 1644 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context, |
1649 Handle<String>* out, | 1645 Handle<String>* out, |
1650 bool* ok) { | 1646 bool* ok) { |
1651 // VariableDeclarations :: | 1647 // VariableDeclarations :: |
1652 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 1648 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] |
1653 | 1649 |
1654 Variable::Mode mode = Variable::VAR; | 1650 VariableMode mode = VAR; |
1655 // True if the binding needs initialization. 'let' and 'const' declared | 1651 // True if the binding needs initialization. 'let' and 'const' declared |
1656 // bindings are created uninitialized by their declaration nodes and | 1652 // bindings are created uninitialized by their declaration nodes and |
1657 // need initialization. 'var' declared bindings are always initialized | 1653 // need initialization. 'var' declared bindings are always initialized |
1658 // immediately by their declaration nodes. | 1654 // immediately by their declaration nodes. |
1659 bool needs_init = false; | 1655 bool needs_init = false; |
1660 bool is_const = false; | 1656 bool is_const = false; |
1661 Token::Value init_op = Token::INIT_VAR; | 1657 Token::Value init_op = Token::INIT_VAR; |
1662 if (peek() == Token::VAR) { | 1658 if (peek() == Token::VAR) { |
1663 Consume(Token::VAR); | 1659 Consume(Token::VAR); |
1664 } else if (peek() == Token::CONST) { | 1660 } else if (peek() == Token::CONST) { |
1665 Consume(Token::CONST); | 1661 Consume(Token::CONST); |
1666 if (top_scope_->is_strict_mode()) { | 1662 if (top_scope_->is_strict_mode()) { |
1667 ReportMessage("strict_const", Vector<const char*>::empty()); | 1663 ReportMessage("strict_const", Vector<const char*>::empty()); |
1668 *ok = false; | 1664 *ok = false; |
1669 return NULL; | 1665 return NULL; |
1670 } | 1666 } |
1671 mode = Variable::CONST; | 1667 mode = CONST; |
1672 is_const = true; | 1668 is_const = true; |
1673 needs_init = true; | 1669 needs_init = true; |
1674 init_op = Token::INIT_CONST; | 1670 init_op = Token::INIT_CONST; |
1675 } else if (peek() == Token::LET) { | 1671 } else if (peek() == Token::LET) { |
1676 Consume(Token::LET); | 1672 Consume(Token::LET); |
1677 if (var_context != kSourceElement && | 1673 if (var_context != kSourceElement && |
1678 var_context != kForStatement) { | 1674 var_context != kForStatement) { |
1679 ASSERT(var_context == kStatement); | 1675 ASSERT(var_context == kStatement); |
1680 ReportMessage("unprotected_let", Vector<const char*>::empty()); | 1676 ReportMessage("unprotected_let", Vector<const char*>::empty()); |
1681 *ok = false; | 1677 *ok = false; |
1682 return NULL; | 1678 return NULL; |
1683 } | 1679 } |
1684 mode = Variable::LET; | 1680 mode = LET; |
1685 needs_init = true; | 1681 needs_init = true; |
1686 init_op = Token::INIT_LET; | 1682 init_op = Token::INIT_LET; |
1687 } else { | 1683 } else { |
1688 UNREACHABLE(); // by current callers | 1684 UNREACHABLE(); // by current callers |
1689 } | 1685 } |
1690 | 1686 |
1691 Scope* declaration_scope = mode == Variable::LET | 1687 Scope* declaration_scope = mode == LET |
Yang
2011/10/11 07:56:35
Consider adding brackets here for better readabili
fschneider
2011/10/11 11:04:22
Done.
| |
1692 ? top_scope_ : top_scope_->DeclarationScope(); | 1688 ? top_scope_ : top_scope_->DeclarationScope(); |
1693 // The scope of a var/const declared variable anywhere inside a function | 1689 // The scope of a var/const declared variable anywhere inside a function |
1694 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can | 1690 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can |
1695 // transform a source-level var/const declaration into a (Function) | 1691 // transform a source-level var/const declaration into a (Function) |
1696 // Scope declaration, and rewrite the source-level initialization into an | 1692 // Scope declaration, and rewrite the source-level initialization into an |
1697 // assignment statement. We use a block to collect multiple assignments. | 1693 // assignment statement. We use a block to collect multiple assignments. |
1698 // | 1694 // |
1699 // We mark the block as initializer block because we don't want the | 1695 // We mark the block as initializer block because we don't want the |
1700 // rewriter to add a '.result' assignment to such a block (to get compliant | 1696 // rewriter to add a '.result' assignment to such a block (to get compliant |
1701 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 1697 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1872 // statement - they may change a 'with' object property). Constant | 1868 // statement - they may change a 'with' object property). Constant |
1873 // initializations always assign to the declared constant which is | 1869 // initializations always assign to the declared constant which is |
1874 // always at the function scope level. This is only relevant for | 1870 // always at the function scope level. This is only relevant for |
1875 // dynamically looked-up variables and constants (the start context | 1871 // dynamically looked-up variables and constants (the start context |
1876 // for constant lookups is always the function context, while it is | 1872 // for constant lookups is always the function context, while it is |
1877 // the top context for var declared variables). Sigh... | 1873 // the top context for var declared variables). Sigh... |
1878 // For 'let' declared variables the initialization is in the same scope | 1874 // For 'let' declared variables the initialization is in the same scope |
1879 // as the declaration. Thus dynamic lookups are unnecessary even if the | 1875 // as the declaration. Thus dynamic lookups are unnecessary even if the |
1880 // block scope is inside a with. | 1876 // block scope is inside a with. |
1881 if (value != NULL) { | 1877 if (value != NULL) { |
1882 bool in_with = mode == Variable::VAR ? inside_with() : false; | 1878 bool in_with = mode == VAR ? inside_with() : false; |
Yang
2011/10/11 07:56:35
Consider brackets.
fschneider
2011/10/11 11:04:22
Done.
| |
1883 VariableProxy* proxy = | 1879 VariableProxy* proxy = |
1884 initialization_scope->NewUnresolved(name, in_with); | 1880 initialization_scope->NewUnresolved(name, in_with); |
1885 Assignment* assignment = | 1881 Assignment* assignment = |
1886 new(zone()) Assignment(isolate(), init_op, proxy, value, position); | 1882 new(zone()) Assignment(isolate(), init_op, proxy, value, position); |
1887 if (block) { | 1883 if (block) { |
1888 block->AddStatement(new(zone()) ExpressionStatement(assignment)); | 1884 block->AddStatement(new(zone()) ExpressionStatement(assignment)); |
1889 } | 1885 } |
1890 } | 1886 } |
1891 | 1887 |
1892 if (fni_ != NULL) fni_->Leave(); | 1888 if (fni_ != NULL) fni_->Leave(); |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2246 } | 2242 } |
2247 | 2243 |
2248 Expect(Token::RPAREN, CHECK_OK); | 2244 Expect(Token::RPAREN, CHECK_OK); |
2249 | 2245 |
2250 if (peek() == Token::LBRACE) { | 2246 if (peek() == Token::LBRACE) { |
2251 Target target(&this->target_stack_, &catch_collector); | 2247 Target target(&this->target_stack_, &catch_collector); |
2252 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); | 2248 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); |
2253 if (top_scope_->is_strict_mode()) { | 2249 if (top_scope_->is_strict_mode()) { |
2254 catch_scope->EnableStrictMode(); | 2250 catch_scope->EnableStrictMode(); |
2255 } | 2251 } |
2256 Variable::Mode mode = harmony_block_scoping_ | 2252 VariableMode mode = harmony_block_scoping_ ? LET : VAR; |
2257 ? Variable::LET : Variable::VAR; | |
2258 catch_variable = catch_scope->DeclareLocal(name, mode); | 2253 catch_variable = catch_scope->DeclareLocal(name, mode); |
2259 | 2254 |
2260 Scope* saved_scope = top_scope_; | 2255 Scope* saved_scope = top_scope_; |
2261 top_scope_ = catch_scope; | 2256 top_scope_ = catch_scope; |
2262 catch_block = ParseBlock(NULL, CHECK_OK); | 2257 catch_block = ParseBlock(NULL, CHECK_OK); |
2263 top_scope_ = saved_scope; | 2258 top_scope_ = saved_scope; |
2264 } else { | 2259 } else { |
2265 Expect(Token::LBRACE, CHECK_OK); | 2260 Expect(Token::LBRACE, CHECK_OK); |
2266 } | 2261 } |
2267 | 2262 |
(...skipping 1488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3756 } | 3751 } |
3757 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { | 3752 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { |
3758 has_duplicate_parameters = true; | 3753 has_duplicate_parameters = true; |
3759 dupe_loc = scanner().location(); | 3754 dupe_loc = scanner().location(); |
3760 } | 3755 } |
3761 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3756 if (!reserved_loc.IsValid() && is_strict_reserved) { |
3762 reserved_loc = scanner().location(); | 3757 reserved_loc = scanner().location(); |
3763 } | 3758 } |
3764 | 3759 |
3765 top_scope_->DeclareParameter(param_name, | 3760 top_scope_->DeclareParameter(param_name, |
3766 harmony_block_scoping_ | 3761 harmony_block_scoping_ ? LET : VAR); |
3767 ? Variable::LET | |
3768 : Variable::VAR); | |
3769 num_parameters++; | 3762 num_parameters++; |
3770 if (num_parameters > kMaxNumFunctionParameters) { | 3763 if (num_parameters > kMaxNumFunctionParameters) { |
3771 ReportMessageAt(scanner().location(), "too_many_parameters", | 3764 ReportMessageAt(scanner().location(), "too_many_parameters", |
3772 Vector<const char*>::empty()); | 3765 Vector<const char*>::empty()); |
3773 *ok = false; | 3766 *ok = false; |
3774 return NULL; | 3767 return NULL; |
3775 } | 3768 } |
3776 done = (peek() == Token::RPAREN); | 3769 done = (peek() == Token::RPAREN); |
3777 if (!done) Expect(Token::COMMA, CHECK_OK); | 3770 if (!done) Expect(Token::COMMA, CHECK_OK); |
3778 } | 3771 } |
(...skipping 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5235 result = parser.ParseProgram(source, | 5228 result = parser.ParseProgram(source, |
5236 info->is_global(), | 5229 info->is_global(), |
5237 info->StrictMode()); | 5230 info->StrictMode()); |
5238 } | 5231 } |
5239 } | 5232 } |
5240 info->SetFunction(result); | 5233 info->SetFunction(result); |
5241 return (result != NULL); | 5234 return (result != NULL); |
5242 } | 5235 } |
5243 | 5236 |
5244 } } // namespace v8::internal | 5237 } } // namespace v8::internal |
OLD | NEW |