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

Side by Side Diff: src/parser.cc

Issue 7280012: Introduce scopes to keep track of catch blocks at compile time. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Update to HEAD. Created 9 years, 5 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
OLDNEW
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 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 return &store_[PreparseDataConstants::kHeaderSize + position]; 404 return &store_[PreparseDataConstants::kHeaderSize + position];
405 } 405 }
406 406
407 407
408 Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) { 408 Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) {
409 Scope* result = new(zone()) Scope(parent, type); 409 Scope* result = new(zone()) Scope(parent, type);
410 result->Initialize(inside_with); 410 result->Initialize(inside_with);
411 return result; 411 return result;
412 } 412 }
413 413
414
415 Scope* Parser::DeclarationScope() {
Kevin Millikin (Chromium) 2011/06/30 09:28:45 As an alternative, we could keep a pair of scopes.
416 Scope* scope = top_scope_;
417 while (scope->is_catch_scope()) {
418 scope = scope->outer_scope();
419 }
420 return scope;
421 }
422
414 // ---------------------------------------------------------------------------- 423 // ----------------------------------------------------------------------------
415 // Target is a support class to facilitate manipulation of the 424 // Target is a support class to facilitate manipulation of the
416 // Parser's target_stack_ (the stack of potential 'break' and 425 // Parser's target_stack_ (the stack of potential 'break' and
417 // 'continue' statement targets). Upon construction, a new target is 426 // 'continue' statement targets). Upon construction, a new target is
418 // added; it is removed upon destruction. 427 // added; it is removed upon destruction.
419 428
420 class Target BASE_EMBEDDED { 429 class Target BASE_EMBEDDED {
421 public: 430 public:
422 Target(Target** variable, AstNode* node) 431 Target(Target** variable, AstNode* node)
423 : variable_(variable), node_(node), previous_(*variable) { 432 : variable_(variable), node_(node), previous_(*variable) {
(...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 // is always the function scope. 1303 // is always the function scope.
1295 1304
1296 // If a function scope exists, then we can statically declare this 1305 // If a function scope exists, then we can statically declare this
1297 // variable and also set its mode. In any case, a Declaration node 1306 // variable and also set its mode. In any case, a Declaration node
1298 // will be added to the scope so that the declaration can be added 1307 // will be added to the scope so that the declaration can be added
1299 // to the corresponding activation frame at runtime if necessary. 1308 // to the corresponding activation frame at runtime if necessary.
1300 // For instance declarations inside an eval scope need to be added 1309 // For instance declarations inside an eval scope need to be added
1301 // to the calling function context. 1310 // to the calling function context.
1302 // Similarly, strict mode eval scope does not leak variable declarations to 1311 // Similarly, strict mode eval scope does not leak variable declarations to
1303 // the caller's scope so we declare all locals, too. 1312 // the caller's scope so we declare all locals, too.
1304 if (top_scope_->is_function_scope() || 1313 Scope* declaration_scope = DeclarationScope();
1305 top_scope_->is_strict_mode_eval_scope()) { 1314 if (declaration_scope->is_function_scope() ||
1315 declaration_scope->is_strict_mode_eval_scope()) {
1306 // Declare the variable in the function scope. 1316 // Declare the variable in the function scope.
1307 var = top_scope_->LocalLookup(name); 1317 var = declaration_scope->LocalLookup(name);
1308 if (var == NULL) { 1318 if (var == NULL) {
1309 // Declare the name. 1319 // Declare the name.
1310 var = top_scope_->DeclareLocal(name, mode); 1320 var = declaration_scope->DeclareLocal(name, mode);
1311 } else { 1321 } else {
1312 // The name was declared before; check for conflicting 1322 // The name was declared before; check for conflicting
1313 // re-declarations. If the previous declaration was a const or the 1323 // re-declarations. If the previous declaration was a const or the
1314 // current declaration is a const then we have a conflict. There is 1324 // current declaration is a const then we have a conflict. There is
1315 // similar code in runtime.cc in the Declare functions. 1325 // similar code in runtime.cc in the Declare functions.
1316 if ((mode == Variable::CONST) || (var->mode() == Variable::CONST)) { 1326 if ((mode == Variable::CONST) || (var->mode() == Variable::CONST)) {
1317 // We only have vars and consts in declarations. 1327 // We only have vars and consts in declarations.
1318 ASSERT(var->mode() == Variable::VAR || 1328 ASSERT(var->mode() == Variable::VAR ||
1319 var->mode() == Variable::CONST); 1329 var->mode() == Variable::CONST);
1320 const char* type = (var->mode() == Variable::VAR) ? "var" : "const"; 1330 const char* type = (var->mode() == Variable::VAR) ? "var" : "const";
1321 Handle<String> type_string = 1331 Handle<String> type_string =
1322 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); 1332 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
1323 Expression* expression = 1333 Expression* expression =
1324 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), 1334 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1325 type_string, name); 1335 type_string, name);
1326 top_scope_->SetIllegalRedeclaration(expression); 1336 declaration_scope->SetIllegalRedeclaration(expression);
1327 } 1337 }
1328 } 1338 }
1329 } 1339 }
1330 1340
1331 // We add a declaration node for every declaration. The compiler 1341 // We add a declaration node for every declaration. The compiler
1332 // will only generate code if necessary. In particular, declarations 1342 // will only generate code if necessary. In particular, declarations
1333 // for inner local variables that do not represent functions won't 1343 // for inner local variables that do not represent functions won't
1334 // result in any generated code. 1344 // result in any generated code.
1335 // 1345 //
1336 // Note that we always add an unresolved proxy even if it's not 1346 // Note that we always add an unresolved proxy even if it's not
1337 // used, simply because we don't know in this method (w/o extra 1347 // used, simply because we don't know in this method (w/o extra
1338 // parameters) if the proxy is needed or not. The proxy will be 1348 // parameters) if the proxy is needed or not. The proxy will be
1339 // bound during variable resolution time unless it was pre-bound 1349 // bound during variable resolution time unless it was pre-bound
1340 // below. 1350 // below.
1341 // 1351 //
1342 // WARNING: This will lead to multiple declaration nodes for the 1352 // WARNING: This will lead to multiple declaration nodes for the
1343 // same variable if it is declared several times. This is not a 1353 // same variable if it is declared several times. This is not a
1344 // semantic issue as long as we keep the source order, but it may be 1354 // semantic issue as long as we keep the source order, but it may be
1345 // a performance issue since it may lead to repeated 1355 // a performance issue since it may lead to repeated
1346 // Runtime::DeclareContextSlot() calls. 1356 // Runtime::DeclareContextSlot() calls.
1347 VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with()); 1357 VariableProxy* proxy = declaration_scope->NewUnresolved(name, false);
1348 top_scope_->AddDeclaration(new(zone()) Declaration(proxy, mode, fun)); 1358 declaration_scope->AddDeclaration(new(zone()) Declaration(proxy, mode, fun));
1349 1359
1350 // For global const variables we bind the proxy to a variable. 1360 // For global const variables we bind the proxy to a variable.
1351 if (mode == Variable::CONST && top_scope_->is_global_scope()) { 1361 if (mode == Variable::CONST && declaration_scope->is_global_scope()) {
1352 ASSERT(resolve); // should be set by all callers 1362 ASSERT(resolve); // should be set by all callers
1353 Variable::Kind kind = Variable::NORMAL; 1363 Variable::Kind kind = Variable::NORMAL;
1354 var = new(zone()) Variable(top_scope_, name, Variable::CONST, true, kind); 1364 var = new(zone()) Variable(declaration_scope,
1365 name,
1366 Variable::CONST,
1367 true,
1368 kind);
1355 } 1369 }
1356 1370
1357 // If requested and we have a local variable, bind the proxy to the variable 1371 // If requested and we have a local variable, bind the proxy to the variable
1358 // at parse-time. This is used for functions (and consts) declared inside 1372 // at parse-time. This is used for functions (and consts) declared inside
1359 // statements: the corresponding function (or const) variable must be in the 1373 // statements: the corresponding function (or const) variable must be in the
1360 // function scope and not a statement-local scope, e.g. as provided with a 1374 // function scope and not a statement-local scope, e.g. as provided with a
1361 // 'with' statement: 1375 // 'with' statement:
1362 // 1376 //
1363 // with (obj) { 1377 // with (obj) {
1364 // function f() {} 1378 // function f() {}
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 Expect(Token::COMMA, CHECK_OK); 1414 Expect(Token::COMMA, CHECK_OK);
1401 } 1415 }
1402 } 1416 }
1403 Expect(Token::RPAREN, CHECK_OK); 1417 Expect(Token::RPAREN, CHECK_OK);
1404 Expect(Token::SEMICOLON, CHECK_OK); 1418 Expect(Token::SEMICOLON, CHECK_OK);
1405 1419
1406 // Make sure that the function containing the native declaration 1420 // Make sure that the function containing the native declaration
1407 // isn't lazily compiled. The extension structures are only 1421 // isn't lazily compiled. The extension structures are only
1408 // accessible while parsing the first time not when reparsing 1422 // accessible while parsing the first time not when reparsing
1409 // because of lazy compilation. 1423 // because of lazy compilation.
1410 top_scope_->ForceEagerCompilation(); 1424 DeclarationScope()->ForceEagerCompilation();
1411 1425
1412 // Compute the function template for the native function. 1426 // Compute the function template for the native function.
1413 v8::Handle<v8::FunctionTemplate> fun_template = 1427 v8::Handle<v8::FunctionTemplate> fun_template =
1414 extension_->GetNativeFunction(v8::Utils::ToLocal(name)); 1428 extension_->GetNativeFunction(v8::Utils::ToLocal(name));
1415 ASSERT(!fun_template.IsEmpty()); 1429 ASSERT(!fun_template.IsEmpty());
1416 1430
1417 // Instantiate the function and create a shared function info from it. 1431 // Instantiate the function and create a shared function info from it.
1418 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction()); 1432 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
1419 const int literals = fun->NumberOfLiterals(); 1433 const int literals = fun->NumberOfLiterals();
1420 Handle<Code> code = Handle<Code>(fun->shared()->code()); 1434 Handle<Code> code = Handle<Code>(fun->shared()->code());
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 } 1492 }
1479 Expect(Token::RBRACE, CHECK_OK); 1493 Expect(Token::RBRACE, CHECK_OK);
1480 return result; 1494 return result;
1481 } 1495 }
1482 1496
1483 1497
1484 Block* Parser::ParseVariableStatement(bool* ok) { 1498 Block* Parser::ParseVariableStatement(bool* ok) {
1485 // VariableStatement :: 1499 // VariableStatement ::
1486 // VariableDeclarations ';' 1500 // VariableDeclarations ';'
1487 1501
1488 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature 1502 Handle<String> ignore;
1489 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK); 1503 Block* result = ParseVariableDeclarations(true, &ignore, CHECK_OK);
1490 ExpectSemicolon(CHECK_OK); 1504 ExpectSemicolon(CHECK_OK);
1491 return result; 1505 return result;
1492 } 1506 }
1493 1507
1494 1508
1495 bool Parser::IsEvalOrArguments(Handle<String> string) { 1509 bool Parser::IsEvalOrArguments(Handle<String> string) {
1496 return string.is_identical_to(isolate()->factory()->eval_symbol()) || 1510 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
1497 string.is_identical_to(isolate()->factory()->arguments_symbol()); 1511 string.is_identical_to(isolate()->factory()->arguments_symbol());
1498 } 1512 }
1499 1513
1500 1514
1501 // If the variable declaration declares exactly one non-const 1515 // If the variable declaration declares exactly one non-const
1502 // variable, then *var is set to that variable. In all other cases, 1516 // variable, then *var is set to that variable. In all other cases,
1503 // *var is untouched; in particular, it is the caller's responsibility 1517 // *var is untouched; in particular, it is the caller's responsibility
1504 // to initialize it properly. This mechanism is used for the parsing 1518 // to initialize it properly. This mechanism is used for the parsing
1505 // of 'for-in' loops. 1519 // of 'for-in' loops.
1506 Block* Parser::ParseVariableDeclarations(bool accept_IN, 1520 Block* Parser::ParseVariableDeclarations(bool accept_IN,
1507 Expression** var, 1521 Handle<String>* name,
Kevin Millikin (Chromium) 2011/06/30 09:28:45 In most cases (all but 'for (var ... in ...)' the
1508 bool* ok) { 1522 bool* ok) {
1509 // VariableDeclarations :: 1523 // VariableDeclarations ::
1510 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 1524 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
1511 1525
1512 Variable::Mode mode = Variable::VAR; 1526 Variable::Mode mode = Variable::VAR;
1513 bool is_const = false; 1527 bool is_const = false;
1528 Scope* declaration_scope = DeclarationScope();
1514 if (peek() == Token::VAR) { 1529 if (peek() == Token::VAR) {
1515 Consume(Token::VAR); 1530 Consume(Token::VAR);
1516 } else if (peek() == Token::CONST) { 1531 } else if (peek() == Token::CONST) {
1517 Consume(Token::CONST); 1532 Consume(Token::CONST);
1518 if (top_scope_->is_strict_mode()) { 1533 if (declaration_scope->is_strict_mode()) {
1519 ReportMessage("strict_const", Vector<const char*>::empty()); 1534 ReportMessage("strict_const", Vector<const char*>::empty());
1520 *ok = false; 1535 *ok = false;
1521 return NULL; 1536 return NULL;
1522 } 1537 }
1523 mode = Variable::CONST; 1538 mode = Variable::CONST;
1524 is_const = true; 1539 is_const = true;
1525 } else { 1540 } else {
1526 UNREACHABLE(); // by current callers 1541 UNREACHABLE(); // by current callers
1527 } 1542 }
1528 1543
1529 // The scope of a variable/const declared anywhere inside a function 1544 // The scope of a variable/const declared anywhere inside a function
1530 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1545 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
1531 // transform a source-level variable/const declaration into a (Function) 1546 // transform a source-level variable/const declaration into a (Function)
1532 // Scope declaration, and rewrite the source-level initialization into an 1547 // Scope declaration, and rewrite the source-level initialization into an
1533 // assignment statement. We use a block to collect multiple assignments. 1548 // assignment statement. We use a block to collect multiple assignments.
1534 // 1549 //
1535 // We mark the block as initializer block because we don't want the 1550 // We mark the block as initializer block because we don't want the
1536 // rewriter to add a '.result' assignment to such a block (to get compliant 1551 // rewriter to add a '.result' assignment to such a block (to get compliant
1537 // behavior for code such as print(eval('var x = 7')), and for cosmetic 1552 // behavior for code such as print(eval('var x = 7')), and for cosmetic
1538 // reasons when pretty-printing. Also, unless an assignment (initialization) 1553 // reasons when pretty-printing. Also, unless an assignment (initialization)
1539 // is inside an initializer block, it is ignored. 1554 // is inside an initializer block, it is ignored.
1540 // 1555 //
1541 // Create new block with one expected declaration. 1556 // Create new block with one expected declaration.
1542 Block* block = new(zone()) Block(NULL, 1, true); 1557 Block* block = new(zone()) Block(NULL, 1, true);
1543 VariableProxy* last_var = NULL; // the last variable declared
1544 int nvars = 0; // the number of variables declared 1558 int nvars = 0; // the number of variables declared
1545 do { 1559 do {
1546 if (fni_ != NULL) fni_->Enter(); 1560 if (fni_ != NULL) fni_->Enter();
1547 1561
1548 // Parse variable name. 1562 // Parse variable name.
1549 if (nvars > 0) Consume(Token::COMMA); 1563 if (nvars > 0) Consume(Token::COMMA);
1550 Handle<String> name = ParseIdentifier(CHECK_OK); 1564 *name = ParseIdentifier(CHECK_OK);
1551 if (fni_ != NULL) fni_->PushVariableName(name); 1565 if (fni_ != NULL) fni_->PushVariableName(*name);
1552 1566
1553 // Strict mode variables may not be named eval or arguments 1567 // Strict mode variables may not be named eval or arguments
1554 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { 1568 if (declaration_scope->is_strict_mode() && IsEvalOrArguments(*name)) {
1555 ReportMessage("strict_var_name", Vector<const char*>::empty()); 1569 ReportMessage("strict_var_name", Vector<const char*>::empty());
1556 *ok = false; 1570 *ok = false;
1557 return NULL; 1571 return NULL;
1558 } 1572 }
1559 1573
1560 // Declare variable. 1574 // Declare variable.
1561 // Note that we *always* must treat the initial value via a separate init 1575 // Note that we *always* must treat the initial value via a separate init
1562 // assignment for variables and constants because the value must be assigned 1576 // assignment for variables and constants because the value must be assigned
1563 // when the variable is encountered in the source. But the variable/constant 1577 // when the variable is encountered in the source. But the variable/constant
1564 // is declared (and set to 'undefined') upon entering the function within 1578 // is declared (and set to 'undefined') upon entering the function within
1565 // which the variable or constant is declared. Only function variables have 1579 // which the variable or constant is declared. Only function variables have
1566 // an initial value in the declaration (because they are initialized upon 1580 // an initial value in the declaration (because they are initialized upon
1567 // entering the function). 1581 // entering the function).
1568 // 1582 //
1569 // If we have a const declaration, in an inner scope, the proxy is always 1583 // If we have a const declaration, in an inner scope, the proxy is always
1570 // bound to the declared variable (independent of possibly surrounding with 1584 // bound to the declared variable (independent of possibly surrounding with
1571 // statements). 1585 // statements).
1572 last_var = Declare(name, mode, NULL, 1586 Declare(*name, mode, NULL, is_const /* always bound for CONST! */,
1573 is_const /* always bound for CONST! */, 1587 CHECK_OK);
1574 CHECK_OK);
1575 nvars++; 1588 nvars++;
1576 if (top_scope_->num_var_or_const() > kMaxNumFunctionLocals) { 1589 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
1577 ReportMessageAt(scanner().location(), "too_many_variables", 1590 ReportMessageAt(scanner().location(), "too_many_variables",
1578 Vector<const char*>::empty()); 1591 Vector<const char*>::empty());
1579 *ok = false; 1592 *ok = false;
1580 return NULL; 1593 return NULL;
1581 } 1594 }
1582 1595
1583 // Parse initialization expression if present and/or needed. A 1596 // Parse initialization expression if present and/or needed. A
1584 // declaration of the form: 1597 // declaration of the form:
1585 // 1598 //
1586 // var v = x; 1599 // var v = x;
1587 // 1600 //
1588 // is syntactic sugar for: 1601 // is syntactic sugar for:
1589 // 1602 //
1590 // var v; v = x; 1603 // var v; v = x;
1591 // 1604 //
1592 // In particular, we need to re-lookup 'v' as it may be a 1605 // In particular, we need to re-lookup 'v' (in top_scope_, not
1593 // different 'v' than the 'v' in the declaration (if we are inside 1606 // declaration_scope) as it may be a different 'v' than the 'v' in the
1594 // a 'with' statement that makes a object property with name 'v' 1607 // declaration (e.g., if we are inside a 'with' statement or 'catch'
1595 // visible). 1608 // block).
1596 // 1609 //
1597 // However, note that const declarations are different! A const 1610 // However, note that const declarations are different! A const
1598 // declaration of the form: 1611 // declaration of the form:
1599 // 1612 //
1600 // const c = x; 1613 // const c = x;
1601 // 1614 //
1602 // is *not* syntactic sugar for: 1615 // is *not* syntactic sugar for:
1603 // 1616 //
1604 // const c; c = x; 1617 // const c; c = x;
1605 // 1618 //
1606 // The "variable" c initialized to x is the same as the declared 1619 // The "variable" c initialized to x is the same as the declared
1607 // one - there is no re-lookup (see the last parameter of the 1620 // one - there is no re-lookup (see the last parameter of the
1608 // Declare() call above). 1621 // Declare() call above).
1609 1622
1623 Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
Kevin Millikin (Chromium) 2011/06/30 09:28:45 It's subtle that the declaration and initializatio
1610 Expression* value = NULL; 1624 Expression* value = NULL;
1611 int position = -1; 1625 int position = -1;
1612 if (peek() == Token::ASSIGN) { 1626 if (peek() == Token::ASSIGN) {
1613 Expect(Token::ASSIGN, CHECK_OK); 1627 Expect(Token::ASSIGN, CHECK_OK);
1614 position = scanner().location().beg_pos; 1628 position = scanner().location().beg_pos;
1615 value = ParseAssignmentExpression(accept_IN, CHECK_OK); 1629 value = ParseAssignmentExpression(accept_IN, CHECK_OK);
1616 // Don't infer if it is "a = function(){...}();"-like expression. 1630 // Don't infer if it is "a = function(){...}();"-like expression.
1617 if (fni_ != NULL && 1631 if (fni_ != NULL &&
1618 value->AsCall() == NULL && 1632 value->AsCall() == NULL &&
1619 value->AsCallNew() == NULL) { 1633 value->AsCallNew() == NULL) {
(...skipping 20 matching lines...) Expand all
1640 // 1654 //
1641 // Executing the variable declaration statement will always 1655 // Executing the variable declaration statement will always
1642 // guarantee to give the global object a "local" variable; a 1656 // guarantee to give the global object a "local" variable; a
1643 // variable defined in the global object and not in any 1657 // variable defined in the global object and not in any
1644 // prototype. This way, global variable declarations can shadow 1658 // prototype. This way, global variable declarations can shadow
1645 // properties in the prototype chain, but only after the variable 1659 // properties in the prototype chain, but only after the variable
1646 // declaration statement has been executed. This is important in 1660 // declaration statement has been executed. This is important in
1647 // browsers where the global object (window) has lots of 1661 // browsers where the global object (window) has lots of
1648 // properties defined in prototype objects. 1662 // properties defined in prototype objects.
1649 1663
1650 if (top_scope_->is_global_scope()) { 1664 if (initialization_scope->is_global_scope()) {
1651 // Compute the arguments for the runtime call. 1665 // Compute the arguments for the runtime call.
1652 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3); 1666 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3);
1653 // We have at least 1 parameter. 1667 // We have at least 1 parameter.
1654 arguments->Add(new(zone()) Literal(name)); 1668 arguments->Add(new(zone()) Literal(*name));
1655 CallRuntime* initialize; 1669 CallRuntime* initialize;
1656 1670
1657 if (is_const) { 1671 if (is_const) {
1658 arguments->Add(value); 1672 arguments->Add(value);
1659 value = NULL; // zap the value to avoid the unnecessary assignment 1673 value = NULL; // zap the value to avoid the unnecessary assignment
1660 1674
1661 // Construct the call to Runtime_InitializeConstGlobal 1675 // Construct the call to Runtime_InitializeConstGlobal
1662 // and add it to the initialization statement block. 1676 // and add it to the initialization statement block.
1663 // Note that the function does different things depending on 1677 // Note that the function does different things depending on
1664 // the number of arguments (1 or 2). 1678 // the number of arguments (1 or 2).
1665 initialize = 1679 initialize =
1666 new(zone()) CallRuntime( 1680 new(zone()) CallRuntime(
1667 isolate()->factory()->InitializeConstGlobal_symbol(), 1681 isolate()->factory()->InitializeConstGlobal_symbol(),
1668 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), 1682 Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
1669 arguments); 1683 arguments);
1670 } else { 1684 } else {
1671 // Add strict mode. 1685 // Add strict mode.
1672 // We may want to pass singleton to avoid Literal allocations. 1686 // We may want to pass singleton to avoid Literal allocations.
1673 arguments->Add(NewNumberLiteral( 1687 StrictModeFlag flag = initialization_scope->is_strict_mode()
1674 top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode)); 1688 ? kStrictMode
1689 : kNonStrictMode;
1690 arguments->Add(NewNumberLiteral(flag));
1675 1691
1676 // Be careful not to assign a value to the global variable if 1692 // Be careful not to assign a value to the global variable if
1677 // we're in a with. The initialization value should not 1693 // we're in a with. The initialization value should not
1678 // necessarily be stored in the global object in that case, 1694 // necessarily be stored in the global object in that case,
1679 // which is why we need to generate a separate assignment node. 1695 // which is why we need to generate a separate assignment node.
1680 if (value != NULL && !inside_with()) { 1696 if (value != NULL && !inside_with()) {
1681 arguments->Add(value); 1697 arguments->Add(value);
1682 value = NULL; // zap the value to avoid the unnecessary assignment 1698 value = NULL; // zap the value to avoid the unnecessary assignment
1683 } 1699 }
1684 1700
(...skipping 16 matching lines...) Expand all
1701 // between variables and constants: Variable initializations are simply 1717 // between variables and constants: Variable initializations are simply
1702 // assignments (with all the consequences if they are inside a 'with' 1718 // assignments (with all the consequences if they are inside a 'with'
1703 // statement - they may change a 'with' object property). Constant 1719 // statement - they may change a 'with' object property). Constant
1704 // initializations always assign to the declared constant which is 1720 // initializations always assign to the declared constant which is
1705 // always at the function scope level. This is only relevant for 1721 // always at the function scope level. This is only relevant for
1706 // dynamically looked-up variables and constants (the start context 1722 // dynamically looked-up variables and constants (the start context
1707 // for constant lookups is always the function context, while it is 1723 // for constant lookups is always the function context, while it is
1708 // the top context for variables). Sigh... 1724 // the top context for variables). Sigh...
1709 if (value != NULL) { 1725 if (value != NULL) {
1710 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR); 1726 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR);
1727 bool in_with = is_const ? false : inside_with();
1728 VariableProxy* proxy =
1729 initialization_scope->NewUnresolved(*name, in_with);
1711 Assignment* assignment = 1730 Assignment* assignment =
1712 new(zone()) Assignment(op, last_var, value, position); 1731 new(zone()) Assignment(op, proxy, value, position);
1713 if (block) { 1732 if (block) {
1714 block->AddStatement(new(zone()) ExpressionStatement(assignment)); 1733 block->AddStatement(new(zone()) ExpressionStatement(assignment));
1715 } 1734 }
1716 } 1735 }
1717 1736
1718 if (fni_ != NULL) fni_->Leave(); 1737 if (fni_ != NULL) fni_->Leave();
1719 } while (peek() == Token::COMMA); 1738 } while (peek() == Token::COMMA);
1720 1739
1721 if (!is_const && nvars == 1) {
1722 // We have a single, non-const variable.
1723 ASSERT(last_var != NULL);
1724 *var = last_var;
1725 }
1726
1727 return block; 1740 return block;
1728 } 1741 }
1729 1742
1730 1743
1731 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { 1744 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) {
1732 ASSERT(!label.is_null()); 1745 ASSERT(!label.is_null());
1733 if (labels != NULL) 1746 if (labels != NULL)
1734 for (int i = labels->length(); i-- > 0; ) 1747 for (int i = labels->length(); i-- > 0; )
1735 if (labels->at(i).is_identical_to(label)) 1748 if (labels->at(i).is_identical_to(label))
1736 return true; 1749 return true;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1888 // Consume the return token. It is necessary to do the before 1901 // Consume the return token. It is necessary to do the before
1889 // reporting any errors on it, because of the way errors are 1902 // reporting any errors on it, because of the way errors are
1890 // reported (underlining). 1903 // reported (underlining).
1891 Expect(Token::RETURN, CHECK_OK); 1904 Expect(Token::RETURN, CHECK_OK);
1892 1905
1893 // An ECMAScript program is considered syntactically incorrect if it 1906 // An ECMAScript program is considered syntactically incorrect if it
1894 // contains a return statement that is not within the body of a 1907 // contains a return statement that is not within the body of a
1895 // function. See ECMA-262, section 12.9, page 67. 1908 // function. See ECMA-262, section 12.9, page 67.
1896 // 1909 //
1897 // To be consistent with KJS we report the syntax error at runtime. 1910 // To be consistent with KJS we report the syntax error at runtime.
1898 if (!top_scope_->is_function_scope()) { 1911 Scope* declaration_scope = DeclarationScope();
1912 if (declaration_scope->is_global_scope() ||
1913 declaration_scope->is_eval_scope()) {
1899 Handle<String> type = isolate()->factory()->illegal_return_symbol(); 1914 Handle<String> type = isolate()->factory()->illegal_return_symbol();
1900 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); 1915 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
1901 return new(zone()) ExpressionStatement(throw_error); 1916 return new(zone()) ExpressionStatement(throw_error);
1902 } 1917 }
1903 1918
1904 Token::Value tok = peek(); 1919 Token::Value tok = peek();
1905 if (scanner().HasAnyLineTerminatorBeforeNext() || 1920 if (scanner().HasAnyLineTerminatorBeforeNext() ||
1906 tok == Token::SEMICOLON || 1921 tok == Token::SEMICOLON ||
1907 tok == Token::RBRACE || 1922 tok == Token::RBRACE ||
1908 tok == Token::EOS) { 1923 tok == Token::EOS) {
1909 ExpectSemicolon(CHECK_OK); 1924 ExpectSemicolon(CHECK_OK);
1910 return new(zone()) ReturnStatement(GetLiteralUndefined()); 1925 return new(zone()) ReturnStatement(GetLiteralUndefined());
1911 } 1926 }
1912 1927
1913 Expression* expr = ParseExpression(true, CHECK_OK); 1928 Expression* expr = ParseExpression(true, CHECK_OK);
1914 ExpectSemicolon(CHECK_OK); 1929 ExpectSemicolon(CHECK_OK);
1915 return new(zone()) ReturnStatement(expr); 1930 return new(zone()) ReturnStatement(expr);
1916 } 1931 }
1917 1932
1918 1933
1919 Block* Parser::WithHelper(Expression* obj, ZoneStringList* labels, bool* ok) { 1934 Block* Parser::WithHelper(Expression* obj, ZoneStringList* labels, bool* ok) {
1920 // Parse the statement and collect escaping labels. 1935 // Parse the statement and collect escaping labels.
1921 TargetCollector collector; 1936 TargetCollector collector;
1922 Statement* stat; 1937 Statement* stat;
1923 { Target target(&this->target_stack_, &collector); 1938 { Target target(&this->target_stack_, &collector);
1924 with_nesting_level_++; 1939 with_nesting_level_++;
1925 top_scope_->RecordWithStatement(); 1940 DeclarationScope()->RecordWithStatement();
Kevin Millikin (Chromium) 2011/06/30 09:28:45 This is wrong, let's talk about what to do here.
Mads Ager (chromium) 2011/06/30 12:08:32 But it is safe, right?
1926 stat = ParseStatement(labels, CHECK_OK); 1941 stat = ParseStatement(labels, CHECK_OK);
1927 with_nesting_level_--; 1942 with_nesting_level_--;
1928 } 1943 }
1929 // Create resulting block with two statements. 1944 // Create resulting block with two statements.
1930 // 1: Evaluate the with expression. 1945 // 1: Evaluate the with expression.
1931 // 2: The try-finally block evaluating the body. 1946 // 2: The try-finally block evaluating the body.
1932 Block* result = new(zone()) Block(NULL, 2, false); 1947 Block* result = new(zone()) Block(NULL, 2, false);
1933 1948
1934 if (result != NULL) { 1949 if (result != NULL) {
1935 result->AddStatement(new(zone()) EnterWithContextStatement(obj)); 1950 result->AddStatement(new(zone()) EnterWithContextStatement(obj));
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
2075 ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); 2090 ReportMessage("no_catch_or_finally", Vector<const char*>::empty());
2076 *ok = false; 2091 *ok = false;
2077 return NULL; 2092 return NULL;
2078 } 2093 }
2079 2094
2080 // If we can break out from the catch block and there is a finally block, 2095 // If we can break out from the catch block and there is a finally block,
2081 // then we will need to collect escaping targets from the catch 2096 // then we will need to collect escaping targets from the catch
2082 // block. Since we don't know yet if there will be a finally block, we 2097 // block. Since we don't know yet if there will be a finally block, we
2083 // always collect the targets. 2098 // always collect the targets.
2084 TargetCollector catch_collector; 2099 TargetCollector catch_collector;
2100 Scope* catch_scope = NULL;
2101 Variable* catch_variable = NULL;
2085 Block* catch_block = NULL; 2102 Block* catch_block = NULL;
2086 Handle<String> name; 2103 Handle<String> name;
2087 if (tok == Token::CATCH) { 2104 if (tok == Token::CATCH) {
2088 Consume(Token::CATCH); 2105 Consume(Token::CATCH);
2089 2106
2090 Expect(Token::LPAREN, CHECK_OK); 2107 Expect(Token::LPAREN, CHECK_OK);
2091 name = ParseIdentifier(CHECK_OK); 2108 name = ParseIdentifier(CHECK_OK);
2092 2109
2093 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { 2110 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
2094 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); 2111 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2095 *ok = false; 2112 *ok = false;
2096 return NULL; 2113 return NULL;
2097 } 2114 }
2098 2115
2099 Expect(Token::RPAREN, CHECK_OK); 2116 Expect(Token::RPAREN, CHECK_OK);
2100 2117
2101 if (peek() == Token::LBRACE) { 2118 if (peek() == Token::LBRACE) {
2102 // Rewrite the catch body B to a single statement block 2119 // Rewrite the catch body B to a single statement block
2103 // { try B finally { PopContext }}. 2120 // { try B finally { PopContext }}.
2104 Block* inner_body; 2121 Block* inner_body;
2105 // We need to collect escapes from the body for both the inner 2122 // We need to collect escapes from the body for both the inner
2106 // try/finally used to pop the catch context and any possible outer 2123 // try/finally used to pop the catch context and any possible outer
2107 // try/finally. 2124 // try/finally.
2108 TargetCollector inner_collector; 2125 TargetCollector inner_collector;
2109 { Target target(&this->target_stack_, &catch_collector); 2126 { Target target(&this->target_stack_, &catch_collector);
2110 { Target target(&this->target_stack_, &inner_collector); 2127 { Target target(&this->target_stack_, &inner_collector);
2111 ++with_nesting_level_; 2128 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with());
2112 top_scope_->RecordWithStatement(); 2129 if (top_scope_->is_strict_mode()) {
2130 catch_scope->EnableStrictMode();
2131 }
2132 catch_variable = catch_scope->DeclareLocal(name, Variable::VAR);
2133
2134 Scope* saved_scope = top_scope_;
2135 top_scope_ = catch_scope;
2113 inner_body = ParseBlock(NULL, CHECK_OK); 2136 inner_body = ParseBlock(NULL, CHECK_OK);
2114 --with_nesting_level_; 2137 top_scope_ = saved_scope;
2115 } 2138 }
2116 } 2139 }
2117 2140
2118 // Create exit block. 2141 // Create exit block.
2119 Block* inner_finally = new(zone()) Block(NULL, 1, false); 2142 Block* inner_finally = new(zone()) Block(NULL, 1, false);
2120 inner_finally->AddStatement(new(zone()) ExitContextStatement()); 2143 inner_finally->AddStatement(new(zone()) ExitContextStatement());
2121 2144
2122 // Create a try/finally statement. 2145 // Create a try/finally statement.
2123 TryFinallyStatement* inner_try_finally = 2146 TryFinallyStatement* inner_try_finally =
2124 new(zone()) TryFinallyStatement(inner_body, inner_finally); 2147 new(zone()) TryFinallyStatement(inner_body, inner_finally);
(...skipping 13 matching lines...) Expand all
2138 Consume(Token::FINALLY); 2161 Consume(Token::FINALLY);
2139 finally_block = ParseBlock(NULL, CHECK_OK); 2162 finally_block = ParseBlock(NULL, CHECK_OK);
2140 } 2163 }
2141 2164
2142 // Simplify the AST nodes by converting: 2165 // Simplify the AST nodes by converting:
2143 // 'try B0 catch B1 finally B2' 2166 // 'try B0 catch B1 finally B2'
2144 // to: 2167 // to:
2145 // 'try { try B0 catch B1 } finally B2' 2168 // 'try { try B0 catch B1 } finally B2'
2146 2169
2147 if (catch_block != NULL && finally_block != NULL) { 2170 if (catch_block != NULL && finally_block != NULL) {
2171 // If we have both, create an inner try/catch.
2172 ASSERT(catch_scope != NULL && catch_variable != NULL);
2148 TryCatchStatement* statement = 2173 TryCatchStatement* statement =
2149 new(zone()) TryCatchStatement(try_block, name, catch_block); 2174 new(zone()) TryCatchStatement(try_block,
2175 catch_scope,
2176 catch_variable,
2177 catch_block);
2150 statement->set_escaping_targets(try_collector.targets()); 2178 statement->set_escaping_targets(try_collector.targets());
2151 try_block = new(zone()) Block(NULL, 1, false); 2179 try_block = new(zone()) Block(NULL, 1, false);
2152 try_block->AddStatement(statement); 2180 try_block->AddStatement(statement);
2153 catch_block = NULL; 2181 catch_block = NULL; // Clear to indicate it's been handled.
2154 } 2182 }
2155 2183
2156 TryStatement* result = NULL; 2184 TryStatement* result = NULL;
2157 if (catch_block != NULL) { 2185 if (catch_block != NULL) {
2158 ASSERT(finally_block == NULL); 2186 ASSERT(finally_block == NULL);
2187 ASSERT(catch_scope != NULL && catch_variable != NULL);
2159 result = 2188 result =
2160 new(zone()) TryCatchStatement(try_block, name, catch_block); 2189 new(zone()) TryCatchStatement(try_block,
2190 catch_scope,
2191 catch_variable,
2192 catch_block);
2161 } else { 2193 } else {
2162 ASSERT(finally_block != NULL); 2194 ASSERT(finally_block != NULL);
2163 result = new(zone()) TryFinallyStatement(try_block, finally_block); 2195 result = new(zone()) TryFinallyStatement(try_block, finally_block);
2164 // Combine the jump targets of the try block and the possible catch block. 2196 // Combine the jump targets of the try block and the possible catch block.
2165 try_collector.targets()->AddAll(*catch_collector.targets()); 2197 try_collector.targets()->AddAll(*catch_collector.targets());
2166 } 2198 }
2167 2199
2168 result->set_escaping_targets(try_collector.targets()); 2200 result->set_escaping_targets(try_collector.targets());
2169 return result; 2201 return result;
2170 } 2202 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2223 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { 2255 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
2224 // ForStatement :: 2256 // ForStatement ::
2225 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 2257 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2226 2258
2227 Statement* init = NULL; 2259 Statement* init = NULL;
2228 2260
2229 Expect(Token::FOR, CHECK_OK); 2261 Expect(Token::FOR, CHECK_OK);
2230 Expect(Token::LPAREN, CHECK_OK); 2262 Expect(Token::LPAREN, CHECK_OK);
2231 if (peek() != Token::SEMICOLON) { 2263 if (peek() != Token::SEMICOLON) {
2232 if (peek() == Token::VAR || peek() == Token::CONST) { 2264 if (peek() == Token::VAR || peek() == Token::CONST) {
2233 Expression* each = NULL; 2265 Handle<String> name;
2234 Block* variable_statement = 2266 Block* variable_statement =
2235 ParseVariableDeclarations(false, &each, CHECK_OK); 2267 ParseVariableDeclarations(false, &name, CHECK_OK);
2268 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with());
2269
2236 if (peek() == Token::IN && each != NULL) { 2270 if (peek() == Token::IN && each != NULL) {
2237 ForInStatement* loop = new(zone()) ForInStatement(labels); 2271 ForInStatement* loop = new(zone()) ForInStatement(labels);
2238 Target target(&this->target_stack_, loop); 2272 Target target(&this->target_stack_, loop);
2239 2273
2240 Expect(Token::IN, CHECK_OK); 2274 Expect(Token::IN, CHECK_OK);
2241 Expression* enumerable = ParseExpression(true, CHECK_OK); 2275 Expression* enumerable = ParseExpression(true, CHECK_OK);
2242 Expect(Token::RPAREN, CHECK_OK); 2276 Expect(Token::RPAREN, CHECK_OK);
2243 2277
2244 Statement* body = ParseStatement(NULL, CHECK_OK); 2278 Statement* body = ParseStatement(NULL, CHECK_OK);
2245 loop->Initialize(each, enumerable, body); 2279 loop->Initialize(each, enumerable, body);
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
2894 // String 2928 // String
2895 // ArrayLiteral 2929 // ArrayLiteral
2896 // ObjectLiteral 2930 // ObjectLiteral
2897 // RegExpLiteral 2931 // RegExpLiteral
2898 // '(' Expression ')' 2932 // '(' Expression ')'
2899 2933
2900 Expression* result = NULL; 2934 Expression* result = NULL;
2901 switch (peek()) { 2935 switch (peek()) {
2902 case Token::THIS: { 2936 case Token::THIS: {
2903 Consume(Token::THIS); 2937 Consume(Token::THIS);
2904 VariableProxy* recv = top_scope_->receiver(); 2938 result = new(zone()) VariableProxy(top_scope_->receiver());
2905 result = recv;
2906 break; 2939 break;
2907 } 2940 }
2908 2941
2909 case Token::NULL_LITERAL: 2942 case Token::NULL_LITERAL:
2910 Consume(Token::NULL_LITERAL); 2943 Consume(Token::NULL_LITERAL);
2911 result = new(zone()) Literal(isolate()->factory()->null_value()); 2944 result = new(zone()) Literal(isolate()->factory()->null_value());
2912 break; 2945 break;
2913 2946
2914 case Token::TRUE_LITERAL: 2947 case Token::TRUE_LITERAL:
2915 Consume(Token::TRUE_LITERAL); 2948 Consume(Token::TRUE_LITERAL);
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
3755 // CallRuntime :: 3788 // CallRuntime ::
3756 // '%' Identifier Arguments 3789 // '%' Identifier Arguments
3757 3790
3758 Expect(Token::MOD, CHECK_OK); 3791 Expect(Token::MOD, CHECK_OK);
3759 Handle<String> name = ParseIdentifier(CHECK_OK); 3792 Handle<String> name = ParseIdentifier(CHECK_OK);
3760 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 3793 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3761 3794
3762 if (extension_ != NULL) { 3795 if (extension_ != NULL) {
3763 // The extension structures are only accessible while parsing the 3796 // The extension structures are only accessible while parsing the
3764 // very first time not when reparsing because of lazy compilation. 3797 // very first time not when reparsing because of lazy compilation.
3765 top_scope_->ForceEagerCompilation(); 3798 DeclarationScope()->ForceEagerCompilation();
3766 } 3799 }
3767 3800
3768 const Runtime::Function* function = Runtime::FunctionForSymbol(name); 3801 const Runtime::Function* function = Runtime::FunctionForSymbol(name);
3769 3802
3770 // Check for built-in IS_VAR macro. 3803 // Check for built-in IS_VAR macro.
3771 if (function != NULL && 3804 if (function != NULL &&
3772 function->intrinsic_type == Runtime::RUNTIME && 3805 function->intrinsic_type == Runtime::RUNTIME &&
3773 function->function_id == Runtime::kIS_VAR) { 3806 function->function_id == Runtime::kIS_VAR) {
3774 // %IS_VAR(x) evaluates to x if x is a variable, 3807 // %IS_VAR(x) evaluates to x if x is a variable,
3775 // leads to a parse error otherwise. Could be implemented as an 3808 // leads to a parse error otherwise. Could be implemented as an
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after
5035 info->is_global(), 5068 info->is_global(),
5036 info->StrictMode()); 5069 info->StrictMode());
5037 } 5070 }
5038 } 5071 }
5039 5072
5040 info->SetFunction(result); 5073 info->SetFunction(result);
5041 return (result != NULL); 5074 return (result != NULL);
5042 } 5075 }
5043 5076
5044 } } // namespace v8::internal 5077 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698