| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 state_(NULL), | 85 state_(NULL), |
| 86 is_inside_try_(false), | 86 is_inside_try_(false), |
| 87 break_stack_height_(0), | 87 break_stack_height_(0), |
| 88 loop_nesting_(0), | 88 loop_nesting_(0), |
| 89 function_return_is_shadowed_(false), | 89 function_return_is_shadowed_(false), |
| 90 in_spilled_code_(false) { | 90 in_spilled_code_(false) { |
| 91 } | 91 } |
| 92 | 92 |
| 93 | 93 |
| 94 void CodeGenerator::SetFrame(VirtualFrame* new_frame) { | 94 void CodeGenerator::SetFrame(VirtualFrame* new_frame) { |
| 95 if (frame_ != NULL) { | 95 if (has_valid_frame()) { |
| 96 frame_->DetachFromCodeGenerator(); | 96 frame_->DetachFromCodeGenerator(); |
| 97 } | 97 } |
| 98 if (new_frame != NULL) { | 98 if (new_frame != NULL) { |
| 99 new_frame->AttachToCodeGenerator(); | 99 new_frame->AttachToCodeGenerator(); |
| 100 } | 100 } |
| 101 frame_ = new_frame; | 101 frame_ = new_frame; |
| 102 } | 102 } |
| 103 | 103 |
| 104 | 104 |
| 105 void CodeGenerator::DeleteFrame() { | 105 void CodeGenerator::DeleteFrame() { |
| 106 if (frame_ != NULL) { | 106 if (has_valid_frame()) { |
| 107 frame_->DetachFromCodeGenerator(); | 107 frame_->DetachFromCodeGenerator(); |
| 108 delete frame_; | 108 delete frame_; |
| 109 frame_ = NULL; | 109 frame_ = NULL; |
| 110 } | 110 } |
| 111 } | 111 } |
| 112 | 112 |
| 113 | 113 |
| 114 // Calling conventions: | 114 // Calling conventions: |
| 115 // ebp: frame pointer | 115 // ebp: frame pointer |
| 116 // esp: stack pointer | 116 // esp: stack pointer |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 if (should_trace) { | 283 if (should_trace) { |
| 284 frame_->CallRuntime(Runtime::kDebugTrace, 0); | 284 frame_->CallRuntime(Runtime::kDebugTrace, 0); |
| 285 // Ignore the return value. | 285 // Ignore the return value. |
| 286 } | 286 } |
| 287 #endif | 287 #endif |
| 288 VisitStatements(body); | 288 VisitStatements(body); |
| 289 | 289 |
| 290 // Generate a return statement if necessary. A NULL frame indicates | 290 // Generate a return statement if necessary. A NULL frame indicates |
| 291 // that control flow leaves the body on all paths and cannot fall | 291 // that control flow leaves the body on all paths and cannot fall |
| 292 // through. | 292 // through. |
| 293 if (frame_ != NULL) { | 293 if (has_valid_frame()) { |
| 294 Literal undefined(Factory::undefined_value()); | 294 Literal undefined(Factory::undefined_value()); |
| 295 ReturnStatement statement(&undefined); | 295 ReturnStatement statement(&undefined); |
| 296 statement.set_statement_pos(fun->end_position()); | 296 statement.set_statement_pos(fun->end_position()); |
| 297 VisitReturnStatement(&statement); | 297 VisitReturnStatement(&statement); |
| 298 } | 298 } |
| 299 } | 299 } |
| 300 } | 300 } |
| 301 | 301 |
| 302 // Adjust for function-level loop nesting. | 302 // Adjust for function-level loop nesting. |
| 303 loop_nesting_ -= fun->loop_nesting(); | 303 loop_nesting_ -= fun->loop_nesting(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 JumpTarget* true_target, | 382 JumpTarget* true_target, |
| 383 JumpTarget* false_target, | 383 JumpTarget* false_target, |
| 384 bool force_cc) { | 384 bool force_cc) { |
| 385 ASSERT(!in_spilled_code()); | 385 ASSERT(!in_spilled_code()); |
| 386 ASSERT(!has_cc()); | 386 ASSERT(!has_cc()); |
| 387 | 387 |
| 388 { CodeGenState new_state(this, typeof_state, true_target, false_target); | 388 { CodeGenState new_state(this, typeof_state, true_target, false_target); |
| 389 Visit(x); | 389 Visit(x); |
| 390 } | 390 } |
| 391 | 391 |
| 392 if (force_cc && frame_ != NULL && !has_cc()) { | 392 if (force_cc && has_valid_frame() && !has_cc()) { |
| 393 // Convert the TOS value to a boolean in the condition code register. | 393 // Convert the TOS value to a boolean in the condition code register. |
| 394 VirtualFrame::SpilledScope spilled_scope(this); | 394 VirtualFrame::SpilledScope spilled_scope(this); |
| 395 ToBoolean(true_target, false_target); | 395 ToBoolean(true_target, false_target); |
| 396 } | 396 } |
| 397 | 397 |
| 398 ASSERT(!force_cc || frame_ == NULL || has_cc()); | 398 ASSERT(!force_cc || frame_ == NULL || has_cc()); |
| 399 } | 399 } |
| 400 | 400 |
| 401 | 401 |
| 402 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { | 402 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { |
| 403 ASSERT(!in_spilled_code()); | 403 ASSERT(!in_spilled_code()); |
| 404 JumpTarget true_target(this); | 404 JumpTarget true_target(this); |
| 405 JumpTarget false_target(this); | 405 JumpTarget false_target(this); |
| 406 LoadCondition(x, typeof_state, &true_target, &false_target, false); | 406 LoadCondition(x, typeof_state, &true_target, &false_target, false); |
| 407 | 407 |
| 408 if (has_cc()) { | 408 if (has_cc()) { |
| 409 ASSERT(frame_ != NULL); | 409 ASSERT(has_valid_frame()); |
| 410 VirtualFrame::SpilledScope spilled_scope(this); | 410 VirtualFrame::SpilledScope spilled_scope(this); |
| 411 // Convert cc_reg_ into a boolean value. | 411 // Convert cc_reg_ into a boolean value. |
| 412 JumpTarget loaded(this); | 412 JumpTarget loaded(this); |
| 413 JumpTarget materialize_true(this); | 413 JumpTarget materialize_true(this); |
| 414 materialize_true.Branch(cc_reg_); | 414 materialize_true.Branch(cc_reg_); |
| 415 frame_->EmitPush(Immediate(Factory::false_value())); | 415 frame_->EmitPush(Immediate(Factory::false_value())); |
| 416 loaded.Jump(); | 416 loaded.Jump(); |
| 417 materialize_true.Bind(); | 417 materialize_true.Bind(); |
| 418 frame_->EmitPush(Immediate(Factory::true_value())); | 418 frame_->EmitPush(Immediate(Factory::true_value())); |
| 419 loaded.Bind(); | 419 loaded.Bind(); |
| 420 cc_reg_ = no_condition; | 420 cc_reg_ = no_condition; |
| 421 } | 421 } |
| 422 | 422 |
| 423 if (true_target.is_linked() || false_target.is_linked()) { | 423 if (true_target.is_linked() || false_target.is_linked()) { |
| 424 // We have at least one condition value that has been "translated" into | 424 // We have at least one condition value that has been "translated" into |
| 425 // a branch, thus it needs to be loaded explicitly. | 425 // a branch, thus it needs to be loaded explicitly. |
| 426 JumpTarget loaded(this); | 426 JumpTarget loaded(this); |
| 427 if (frame_ != NULL) { | 427 if (has_valid_frame()) { |
| 428 loaded.Jump(); // Don't lose the current TOS. | 428 loaded.Jump(); // Don't lose the current TOS. |
| 429 } | 429 } |
| 430 bool both = true_target.is_linked() && false_target.is_linked(); | 430 bool both = true_target.is_linked() && false_target.is_linked(); |
| 431 // Load "true" if necessary. | 431 // Load "true" if necessary. |
| 432 if (true_target.is_linked()) { | 432 if (true_target.is_linked()) { |
| 433 true_target.Bind(); | 433 true_target.Bind(); |
| 434 VirtualFrame::SpilledScope spilled_scope(this); | 434 VirtualFrame::SpilledScope spilled_scope(this); |
| 435 frame_->EmitPush(Immediate(Factory::true_value())); | 435 frame_->EmitPush(Immediate(Factory::true_value())); |
| 436 } | 436 } |
| 437 // If both "true" and "false" need to be reincarnated jump across the | 437 // If both "true" and "false" need to be reincarnated jump across the |
| 438 // code for "false". | 438 // code for "false". |
| 439 if (both) { | 439 if (both) { |
| 440 loaded.Jump(); | 440 loaded.Jump(); |
| 441 } | 441 } |
| 442 // Load "false" if necessary. | 442 // Load "false" if necessary. |
| 443 if (false_target.is_linked()) { | 443 if (false_target.is_linked()) { |
| 444 false_target.Bind(); | 444 false_target.Bind(); |
| 445 VirtualFrame::SpilledScope spilled_scope(this); | 445 VirtualFrame::SpilledScope spilled_scope(this); |
| 446 frame_->EmitPush(Immediate(Factory::false_value())); | 446 frame_->EmitPush(Immediate(Factory::false_value())); |
| 447 } | 447 } |
| 448 // A value is loaded on all paths reaching this point. | 448 // A value is loaded on all paths reaching this point. |
| 449 loaded.Bind(); | 449 loaded.Bind(); |
| 450 } | 450 } |
| 451 ASSERT(frame_ != NULL); | 451 ASSERT(has_valid_frame()); |
| 452 ASSERT(!has_cc()); | 452 ASSERT(!has_cc()); |
| 453 } | 453 } |
| 454 | 454 |
| 455 | 455 |
| 456 void CodeGenerator::LoadGlobal() { | 456 void CodeGenerator::LoadGlobal() { |
| 457 frame_->EmitPush(GlobalObject()); | 457 frame_->EmitPush(GlobalObject()); |
| 458 } | 458 } |
| 459 | 459 |
| 460 | 460 |
| 461 void CodeGenerator::LoadGlobalReceiver(Register scratch) { | 461 void CodeGenerator::LoadGlobalReceiver(Register scratch) { |
| (...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1350 // values including constants must be spilled to the frame. | 1350 // values including constants must be spilled to the frame. |
| 1351 frame_->SpillAll(); | 1351 frame_->SpillAll(); |
| 1352 frame_->CallStub(&stub, 0); | 1352 frame_->CallStub(&stub, 0); |
| 1353 stack_is_ok.Bind(); | 1353 stack_is_ok.Bind(); |
| 1354 } | 1354 } |
| 1355 } | 1355 } |
| 1356 | 1356 |
| 1357 | 1357 |
| 1358 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { | 1358 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { |
| 1359 ASSERT(!in_spilled_code()); | 1359 ASSERT(!in_spilled_code()); |
| 1360 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { | 1360 for (int i = 0; has_valid_frame() && i < statements->length(); i++) { |
| 1361 Visit(statements->at(i)); | 1361 Visit(statements->at(i)); |
| 1362 } | 1362 } |
| 1363 } | 1363 } |
| 1364 | 1364 |
| 1365 | 1365 |
| 1366 void CodeGenerator::VisitBlock(Block* node) { | 1366 void CodeGenerator::VisitBlock(Block* node) { |
| 1367 ASSERT(!in_spilled_code()); | 1367 ASSERT(!in_spilled_code()); |
| 1368 Comment cmnt(masm_, "[ Block"); | 1368 Comment cmnt(masm_, "[ Block"); |
| 1369 CodeForStatement(node); | 1369 CodeForStatement(node); |
| 1370 node->set_break_stack_height(break_stack_height_); | 1370 node->set_break_stack_height(break_stack_height_); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1481 bool has_else_stm = node->HasElseStatement(); | 1481 bool has_else_stm = node->HasElseStatement(); |
| 1482 | 1482 |
| 1483 CodeForStatement(node); | 1483 CodeForStatement(node); |
| 1484 JumpTarget exit(this); | 1484 JumpTarget exit(this); |
| 1485 if (has_then_stm && has_else_stm) { | 1485 if (has_then_stm && has_else_stm) { |
| 1486 JumpTarget then(this); | 1486 JumpTarget then(this); |
| 1487 JumpTarget else_(this); | 1487 JumpTarget else_(this); |
| 1488 // if (cond) | 1488 // if (cond) |
| 1489 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | 1489 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, |
| 1490 &then, &else_, true); | 1490 &then, &else_, true); |
| 1491 if (frame_ != NULL) { | 1491 // An invalid frame here indicates that the code for the condition |
| 1492 // A NULL frame here indicates that the code for the condition cannot | 1492 // cannot fall-through, i.e. it caused unconditional jumps to the |
| 1493 // fall-through, i.e. it causes unconditional branchs to targets. | 1493 // targets. |
| 1494 if (has_valid_frame()) { |
| 1494 Branch(false, &else_); | 1495 Branch(false, &else_); |
| 1495 } | 1496 } |
| 1496 // then | 1497 // then |
| 1497 if (frame_ != NULL || then.is_linked()) { | 1498 if (has_valid_frame() || then.is_linked()) { |
| 1498 // If control flow can reach the then part via fall-through from the | 1499 // If control flow can reach the then part via fall-through from the |
| 1499 // test or a branch to the target, compile it. | 1500 // test or a branch to the target, compile it. |
| 1500 then.Bind(); | 1501 then.Bind(); |
| 1501 VisitAndSpill(node->then_statement()); | 1502 VisitAndSpill(node->then_statement()); |
| 1502 } | 1503 } |
| 1503 if (frame_ != NULL) { | 1504 // A NULL frame here indicates that control did not fall out of the then |
| 1504 // A NULL frame here indicates that control did not fall out of the | 1505 // statement, it escaped on all branches. In that case, a jump to the |
| 1505 // then statement, it escaped on all branches. In that case, a jump | 1506 // exit label would be dead code (and impossible, because we don't have |
| 1506 // to the exit label would be dead code (and impossible, because we | 1507 // a current virtual frame to set at the exit label). |
| 1507 // don't have a current virtual frame to set at the exit label). | 1508 if (has_valid_frame()) { |
| 1508 exit.Jump(); | 1509 exit.Jump(); |
| 1509 } | 1510 } |
| 1510 // else | 1511 // else |
| 1511 if (else_.is_linked()) { | 1512 if (else_.is_linked()) { |
| 1512 // Control flow for if-then-else does not fall-through to the else | 1513 // Control flow for if-then-else does not fall-through to the else |
| 1513 // part, it can only reach here via jump if at all. | 1514 // part, it can only reach here via jump if at all. |
| 1514 else_.Bind(); | 1515 else_.Bind(); |
| 1515 VisitAndSpill(node->else_statement()); | 1516 VisitAndSpill(node->else_statement()); |
| 1516 } | 1517 } |
| 1517 | 1518 |
| 1518 } else if (has_then_stm) { | 1519 } else if (has_then_stm) { |
| 1519 ASSERT(!has_else_stm); | 1520 ASSERT(!has_else_stm); |
| 1520 JumpTarget then(this); | 1521 JumpTarget then(this); |
| 1521 // if (cond) | 1522 // if (cond) |
| 1522 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | 1523 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, |
| 1523 &then, &exit, true); | 1524 &then, &exit, true); |
| 1524 if (frame_ != NULL) { | 1525 if (has_valid_frame()) { |
| 1525 Branch(false, &exit); | 1526 Branch(false, &exit); |
| 1526 } | 1527 } |
| 1527 // then | 1528 // then |
| 1528 if (frame_ != NULL || then.is_linked()) { | 1529 if (has_valid_frame() || then.is_linked()) { |
| 1529 then.Bind(); | 1530 then.Bind(); |
| 1530 VisitAndSpill(node->then_statement()); | 1531 VisitAndSpill(node->then_statement()); |
| 1531 } | 1532 } |
| 1532 | 1533 |
| 1533 } else if (has_else_stm) { | 1534 } else if (has_else_stm) { |
| 1534 ASSERT(!has_then_stm); | 1535 ASSERT(!has_then_stm); |
| 1535 JumpTarget else_(this); | 1536 JumpTarget else_(this); |
| 1536 // if (!cond) | 1537 // if (!cond) |
| 1537 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | 1538 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, |
| 1538 &exit, &else_, true); | 1539 &exit, &else_, true); |
| 1539 if (frame_ != NULL) { | 1540 if (has_valid_frame()) { |
| 1540 Branch(true, &exit); | 1541 Branch(true, &exit); |
| 1541 } | 1542 } |
| 1542 // else | 1543 // else |
| 1543 if (frame_ != NULL || else_.is_linked()) { | 1544 if (has_valid_frame() || else_.is_linked()) { |
| 1544 else_.Bind(); | 1545 else_.Bind(); |
| 1545 VisitAndSpill(node->else_statement()); | 1546 VisitAndSpill(node->else_statement()); |
| 1546 } | 1547 } |
| 1547 | 1548 |
| 1548 } else { | 1549 } else { |
| 1549 ASSERT(!has_then_stm && !has_else_stm); | 1550 ASSERT(!has_then_stm && !has_else_stm); |
| 1550 // if (cond) | 1551 // if (cond) |
| 1551 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | 1552 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, |
| 1552 &exit, &exit, false); | 1553 &exit, &exit, false); |
| 1553 if (frame_ != NULL) { | 1554 if (has_valid_frame()) { |
| 1554 if (has_cc()) { | 1555 if (has_cc()) { |
| 1555 cc_reg_ = no_condition; | 1556 cc_reg_ = no_condition; |
| 1556 } else { | 1557 } else { |
| 1557 // No cc value set up, that means the boolean was pushed. | 1558 // No cc value set up, that means the boolean was pushed. |
| 1558 // Pop it again, since it is not going to be used. | 1559 // Pop it again, since it is not going to be used. |
| 1559 frame_->Drop(); | 1560 frame_->Drop(); |
| 1560 } | 1561 } |
| 1561 } | 1562 } |
| 1562 } | 1563 } |
| 1563 | 1564 |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1799 if (i > 0 && cases->at(i - 1)->is_default()) { | 1800 if (i > 0 && cases->at(i - 1)->is_default()) { |
| 1800 default_exit.Bind(); | 1801 default_exit.Bind(); |
| 1801 } else { | 1802 } else { |
| 1802 fall_through.Bind(); | 1803 fall_through.Bind(); |
| 1803 fall_through.Unuse(); | 1804 fall_through.Unuse(); |
| 1804 } | 1805 } |
| 1805 VisitStatementsAndSpill(clause->statements()); | 1806 VisitStatementsAndSpill(clause->statements()); |
| 1806 | 1807 |
| 1807 // If control flow can fall through from the body, jump to the next body | 1808 // If control flow can fall through from the body, jump to the next body |
| 1808 // or the end of the statement. | 1809 // or the end of the statement. |
| 1809 if (frame_ != NULL) { | 1810 if (has_valid_frame()) { |
| 1810 if (i < length - 1 && cases->at(i + 1)->is_default()) { | 1811 if (i < length - 1 && cases->at(i + 1)->is_default()) { |
| 1811 default_entry.Jump(); | 1812 default_entry.Jump(); |
| 1812 } else { | 1813 } else { |
| 1813 fall_through.Jump(); | 1814 fall_through.Jump(); |
| 1814 } | 1815 } |
| 1815 } | 1816 } |
| 1816 } | 1817 } |
| 1817 | 1818 |
| 1818 // The final "test" removes the switch value. | 1819 // The final "test" removes the switch value. |
| 1819 next_test.Bind(); | 1820 next_test.Bind(); |
| 1820 frame_->Drop(); | 1821 frame_->Drop(); |
| 1821 | 1822 |
| 1822 // If there is a default clause, compile it. | 1823 // If there is a default clause, compile it. |
| 1823 if (default_clause != NULL) { | 1824 if (default_clause != NULL) { |
| 1824 Comment cmnt(masm_, "[ Default clause"); | 1825 Comment cmnt(masm_, "[ Default clause"); |
| 1825 default_entry.Bind(); | 1826 default_entry.Bind(); |
| 1826 VisitStatementsAndSpill(default_clause->statements()); | 1827 VisitStatementsAndSpill(default_clause->statements()); |
| 1827 if (frame_ != NULL) { | |
| 1828 } | |
| 1829 // If control flow can fall out of the default and there is a case after | 1828 // If control flow can fall out of the default and there is a case after |
| 1830 // it, jump to that case's body. | 1829 // it, jump to that case's body. |
| 1831 if (frame_ != NULL && default_exit.is_bound()) { | 1830 if (has_valid_frame() && default_exit.is_bound()) { |
| 1832 default_exit.Jump(); | 1831 default_exit.Jump(); |
| 1833 } | 1832 } |
| 1834 } | 1833 } |
| 1835 | 1834 |
| 1836 if (fall_through.is_linked()) { | 1835 if (fall_through.is_linked()) { |
| 1837 fall_through.Bind(); | 1836 fall_through.Bind(); |
| 1838 } | 1837 } |
| 1839 | 1838 |
| 1840 if (node->break_target()->is_linked()) { | 1839 if (node->break_target()->is_linked()) { |
| 1841 node->break_target()->Bind(); | 1840 node->break_target()->Bind(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1881 // There is no need, we will never jump back. | 1880 // There is no need, we will never jump back. |
| 1882 } else { | 1881 } else { |
| 1883 ASSERT(info == DONT_KNOW); | 1882 ASSERT(info == DONT_KNOW); |
| 1884 body.Bind(); | 1883 body.Bind(); |
| 1885 } | 1884 } |
| 1886 CheckStack(); // TODO(1222600): ignore if body contains calls. | 1885 CheckStack(); // TODO(1222600): ignore if body contains calls. |
| 1887 VisitAndSpill(node->body()); | 1886 VisitAndSpill(node->body()); |
| 1888 | 1887 |
| 1889 // Compile the "test". | 1888 // Compile the "test". |
| 1890 if (info == ALWAYS_TRUE) { | 1889 if (info == ALWAYS_TRUE) { |
| 1891 if (frame_ != NULL) { | 1890 if (has_valid_frame()) { |
| 1892 // If control flow can fall off the end of the body, jump back to | 1891 // If control flow can fall off the end of the body, jump back to |
| 1893 // the top. | 1892 // the top. |
| 1894 node->continue_target()->Jump(); | 1893 node->continue_target()->Jump(); |
| 1895 } | 1894 } |
| 1896 } else if (info == ALWAYS_FALSE) { | 1895 } else if (info == ALWAYS_FALSE) { |
| 1897 // If we have a continue in the body, we only have to bind its jump | 1896 // If we have a continue in the body, we only have to bind its jump |
| 1898 // target. | 1897 // target. |
| 1899 if (node->continue_target()->is_linked()) { | 1898 if (node->continue_target()->is_linked()) { |
| 1900 node->continue_target()->Bind(); | 1899 node->continue_target()->Bind(); |
| 1901 } | 1900 } |
| 1902 } else { | 1901 } else { |
| 1903 ASSERT(info == DONT_KNOW); | 1902 ASSERT(info == DONT_KNOW); |
| 1904 // We have to compile the test expression if it can be reached by | 1903 // We have to compile the test expression if it can be reached by |
| 1905 // control flow falling out of the body or via continue. | 1904 // control flow falling out of the body or via continue. |
| 1906 if (frame_ != NULL || node->continue_target()->is_linked()) { | 1905 if (has_valid_frame() || node->continue_target()->is_linked()) { |
| 1907 node->continue_target()->Bind(); | 1906 node->continue_target()->Bind(); |
| 1908 LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF, | 1907 LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF, |
| 1909 &body, node->break_target(), true); | 1908 &body, node->break_target(), true); |
| 1910 if (frame_ != NULL) { | 1909 // An invalid frame here indicates that control flow did not fall |
| 1911 // A NULL frame here indicates that control flow did not fall | 1910 // out of the test expression. |
| 1912 // out of the test expression. | 1911 if (has_valid_frame()) { |
| 1913 Branch(true, &body); | 1912 Branch(true, &body); |
| 1914 } | 1913 } |
| 1915 } | 1914 } |
| 1916 } | 1915 } |
| 1917 break; | 1916 break; |
| 1918 } | 1917 } |
| 1919 | 1918 |
| 1920 case LoopStatement::WHILE_LOOP: { | 1919 case LoopStatement::WHILE_LOOP: { |
| 1921 // The new code generator does not yet compile while loops. | 1920 // The new code generator does not yet compile while loops. |
| 1922 VirtualFrame::SpilledScope spilled_scope(this); | 1921 VirtualFrame::SpilledScope spilled_scope(this); |
| 1923 JumpTarget body(this); | 1922 JumpTarget body(this); |
| 1924 IncrementLoopNesting(); | 1923 IncrementLoopNesting(); |
| 1925 // Generate the loop header. | 1924 // Generate the loop header. |
| 1926 if (info == ALWAYS_TRUE) { | 1925 if (info == ALWAYS_TRUE) { |
| 1927 // Merely label the body with the continue target. | 1926 // Merely label the body with the continue target. |
| 1928 node->continue_target()->Bind(); | 1927 node->continue_target()->Bind(); |
| 1929 } else if (info == ALWAYS_FALSE) { | 1928 } else if (info == ALWAYS_FALSE) { |
| 1930 // There is no need to even compile the test or body. | 1929 // There is no need to even compile the test or body. |
| 1931 break; | 1930 break; |
| 1932 } else { | 1931 } else { |
| 1933 // Compile the test labeled with the continue target and label the | 1932 // Compile the test labeled with the continue target and label the |
| 1934 // body with the body target. | 1933 // body with the body target. |
| 1935 ASSERT(info == DONT_KNOW); | 1934 ASSERT(info == DONT_KNOW); |
| 1936 node->continue_target()->Bind(); | 1935 node->continue_target()->Bind(); |
| 1937 LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF, | 1936 LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF, |
| 1938 &body, node->break_target(), true); | 1937 &body, node->break_target(), true); |
| 1939 if (frame_ != NULL) { | 1938 // An invalid frame indicates that control did not fall out of the |
| 1940 // A NULL frame indicates that control did not fall out of the | 1939 // test expression. |
| 1941 // test expression. | 1940 if (has_valid_frame()) { |
| 1942 Branch(false, node->break_target()); | 1941 Branch(false, node->break_target()); |
| 1943 } | 1942 } |
| 1944 if (frame_ != NULL || body.is_linked()) { | 1943 if (has_valid_frame() || body.is_linked()) { |
| 1945 body.Bind(); | 1944 body.Bind(); |
| 1946 } | 1945 } |
| 1947 } | 1946 } |
| 1948 if (frame_ != NULL) { | 1947 if (has_valid_frame()) { |
| 1949 CheckStack(); // TODO(1222600): ignore if body contains calls. | 1948 CheckStack(); // TODO(1222600): ignore if body contains calls. |
| 1950 VisitAndSpill(node->body()); | 1949 VisitAndSpill(node->body()); |
| 1951 | 1950 |
| 1952 // If control flow can fall out of the body, jump back to the top. | 1951 // If control flow can fall out of the body, jump back to the top. |
| 1953 if (frame_ != NULL) { | 1952 if (has_valid_frame()) { |
| 1954 node->continue_target()->Jump(); | 1953 node->continue_target()->Jump(); |
| 1955 } | 1954 } |
| 1956 } | 1955 } |
| 1957 break; | 1956 break; |
| 1958 } | 1957 } |
| 1959 | 1958 |
| 1960 case LoopStatement::FOR_LOOP: { | 1959 case LoopStatement::FOR_LOOP: { |
| 1961 JumpTarget loop(this); | 1960 JumpTarget loop(this); |
| 1962 JumpTarget body(this); | 1961 JumpTarget body(this); |
| 1963 if (node->init() != NULL) { | 1962 if (node->init() != NULL) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1974 if (node->next() == NULL) { | 1973 if (node->next() == NULL) { |
| 1975 node->continue_target()->Bind(); | 1974 node->continue_target()->Bind(); |
| 1976 } else { | 1975 } else { |
| 1977 loop.Bind(); | 1976 loop.Bind(); |
| 1978 } | 1977 } |
| 1979 | 1978 |
| 1980 // If the test is always true, there is no need to compile it. | 1979 // If the test is always true, there is no need to compile it. |
| 1981 if (info == DONT_KNOW) { | 1980 if (info == DONT_KNOW) { |
| 1982 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, | 1981 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, |
| 1983 &body, node->break_target(), true); | 1982 &body, node->break_target(), true); |
| 1984 if (frame_ != NULL) { | 1983 if (has_valid_frame()) { |
| 1985 Branch(false, node->break_target()); | 1984 Branch(false, node->break_target()); |
| 1986 } | 1985 } |
| 1987 if (frame_ != NULL || body.is_linked()) { | 1986 if (has_valid_frame() || body.is_linked()) { |
| 1988 body.Bind(); | 1987 body.Bind(); |
| 1989 } | 1988 } |
| 1990 } | 1989 } |
| 1991 | 1990 |
| 1992 if (frame_ != NULL) { | 1991 if (has_valid_frame()) { |
| 1993 CheckStack(); // TODO(1222600): ignore if body contains calls. | 1992 CheckStack(); // TODO(1222600): ignore if body contains calls. |
| 1994 Visit(node->body()); | 1993 Visit(node->body()); |
| 1995 | 1994 |
| 1996 if (node->next() == NULL) { | 1995 if (node->next() == NULL) { |
| 1997 // If there is no update statement and control flow can fall out | 1996 // If there is no update statement and control flow can fall out |
| 1998 // of the loop, jump to the continue label. | 1997 // of the loop, jump to the continue label. |
| 1999 if (frame_ != NULL) { | 1998 if (has_valid_frame()) { |
| 2000 node->continue_target()->Jump(); | 1999 node->continue_target()->Jump(); |
| 2001 } | 2000 } |
| 2002 } else { | 2001 } else { |
| 2003 // If there is an update statement and control flow can reach it | 2002 // If there is an update statement and control flow can reach it |
| 2004 // via falling out of the body of the loop or continuing, we | 2003 // via falling out of the body of the loop or continuing, we |
| 2005 // compile the update statement. | 2004 // compile the update statement. |
| 2006 if (frame_ != NULL || node->continue_target()->is_linked()) { | 2005 if (has_valid_frame() || node->continue_target()->is_linked()) { |
| 2007 node->continue_target()->Bind(); | 2006 node->continue_target()->Bind(); |
| 2008 // Record source position of the statement as this code which is | 2007 // Record source position of the statement as this code which is |
| 2009 // after the code for the body actually belongs to the loop | 2008 // after the code for the body actually belongs to the loop |
| 2010 // statement and not the body. | 2009 // statement and not the body. |
| 2011 CodeForStatement(node); | 2010 CodeForStatement(node); |
| 2012 ASSERT(node->type() == LoopStatement::FOR_LOOP); | 2011 ASSERT(node->type() == LoopStatement::FOR_LOOP); |
| 2013 Visit(node->next()); | 2012 Visit(node->next()); |
| 2014 loop.Jump(); | 2013 loop.Jump(); |
| 2015 } | 2014 } |
| 2016 } | 2015 } |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 // Load the exception to the top of the stack. Here we make use of the | 2231 // Load the exception to the top of the stack. Here we make use of the |
| 2233 // convenient property that it doesn't matter whether a value is | 2232 // convenient property that it doesn't matter whether a value is |
| 2234 // immediately on top of or underneath a zero-sized reference. | 2233 // immediately on top of or underneath a zero-sized reference. |
| 2235 ref.SetValue(NOT_CONST_INIT); | 2234 ref.SetValue(NOT_CONST_INIT); |
| 2236 } | 2235 } |
| 2237 | 2236 |
| 2238 // Remove the exception from the stack. | 2237 // Remove the exception from the stack. |
| 2239 frame_->Drop(); | 2238 frame_->Drop(); |
| 2240 | 2239 |
| 2241 VisitStatementsAndSpill(node->catch_block()->statements()); | 2240 VisitStatementsAndSpill(node->catch_block()->statements()); |
| 2242 if (frame_ != NULL) { | 2241 if (has_valid_frame()) { |
| 2243 exit.Jump(); | 2242 exit.Jump(); |
| 2244 } | 2243 } |
| 2245 | 2244 |
| 2246 | 2245 |
| 2247 // --- Try block --- | 2246 // --- Try block --- |
| 2248 try_block.Bind(); | 2247 try_block.Bind(); |
| 2249 | 2248 |
| 2250 frame_->PushTryHandler(TRY_CATCH_HANDLER); | 2249 frame_->PushTryHandler(TRY_CATCH_HANDLER); |
| 2251 int handler_height = frame_->height(); | 2250 int handler_height = frame_->height(); |
| 2252 | 2251 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2287 // Make sure that there's nothing left on the stack above the | 2286 // Make sure that there's nothing left on the stack above the |
| 2288 // handler structure. | 2287 // handler structure. |
| 2289 if (FLAG_debug_code) { | 2288 if (FLAG_debug_code) { |
| 2290 __ mov(eax, Operand::StaticVariable(handler_address)); | 2289 __ mov(eax, Operand::StaticVariable(handler_address)); |
| 2291 __ lea(eax, Operand(eax, StackHandlerConstants::kAddressDisplacement)); | 2290 __ lea(eax, Operand(eax, StackHandlerConstants::kAddressDisplacement)); |
| 2292 __ cmp(esp, Operand(eax)); | 2291 __ cmp(esp, Operand(eax)); |
| 2293 __ Assert(equal, "stack pointer should point to top handler"); | 2292 __ Assert(equal, "stack pointer should point to top handler"); |
| 2294 } | 2293 } |
| 2295 | 2294 |
| 2296 // If we can fall off the end of the try block, unlink from try chain. | 2295 // If we can fall off the end of the try block, unlink from try chain. |
| 2297 if (frame_ != NULL) { | 2296 if (has_valid_frame()) { |
| 2298 frame_->EmitPop(eax); | 2297 frame_->EmitPop(eax); |
| 2299 __ mov(Operand::StaticVariable(handler_address), eax); // TOS == next_sp | 2298 __ mov(Operand::StaticVariable(handler_address), eax); // TOS == next_sp |
| 2300 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 2299 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); |
| 2301 // next_sp popped. | 2300 // next_sp popped. |
| 2302 if (nof_unlinks > 0) { | 2301 if (nof_unlinks > 0) { |
| 2303 exit.Jump(); | 2302 exit.Jump(); |
| 2304 } | 2303 } |
| 2305 } | 2304 } |
| 2306 | 2305 |
| 2307 // Generate unlink code for the (formerly) shadowing targets that have been | 2306 // Generate unlink code for the (formerly) shadowing targets that have been |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2385 // ShadowTargets represent the formerly shadowing targets. | 2384 // ShadowTargets represent the formerly shadowing targets. |
| 2386 int nof_unlinks = 0; | 2385 int nof_unlinks = 0; |
| 2387 for (int i = 0; i <= nof_escapes; i++) { | 2386 for (int i = 0; i <= nof_escapes; i++) { |
| 2388 shadows[i]->StopShadowing(); | 2387 shadows[i]->StopShadowing(); |
| 2389 if (shadows[i]->is_linked()) nof_unlinks++; | 2388 if (shadows[i]->is_linked()) nof_unlinks++; |
| 2390 } | 2389 } |
| 2391 function_return_is_shadowed_ = function_return_was_shadowed; | 2390 function_return_is_shadowed_ = function_return_was_shadowed; |
| 2392 | 2391 |
| 2393 // If we can fall off the end of the try block, set the state on the stack | 2392 // If we can fall off the end of the try block, set the state on the stack |
| 2394 // to FALLING. | 2393 // to FALLING. |
| 2395 if (frame_ != NULL) { | 2394 if (has_valid_frame()) { |
| 2396 frame_->EmitPush(Immediate(Factory::undefined_value())); // fake TOS | 2395 frame_->EmitPush(Immediate(Factory::undefined_value())); // fake TOS |
| 2397 __ Set(ecx, Immediate(Smi::FromInt(FALLING))); | 2396 __ Set(ecx, Immediate(Smi::FromInt(FALLING))); |
| 2398 if (nof_unlinks > 0) { | 2397 if (nof_unlinks > 0) { |
| 2399 unlink.Jump(); | 2398 unlink.Jump(); |
| 2400 } | 2399 } |
| 2401 } | 2400 } |
| 2402 | 2401 |
| 2403 // Generate code to set the state for the (formerly) shadowing targets that | 2402 // Generate code to set the state for the (formerly) shadowing targets that |
| 2404 // have been jumped to. | 2403 // have been jumped to. |
| 2405 for (int i = 0; i <= nof_escapes; i++) { | 2404 for (int i = 0; i <= nof_escapes; i++) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2446 // and the state - while evaluating the finally block. Record it, so | 2445 // and the state - while evaluating the finally block. Record it, so |
| 2447 // that a break/continue crossing this statement can restore the | 2446 // that a break/continue crossing this statement can restore the |
| 2448 // stack. | 2447 // stack. |
| 2449 const int kFinallyStackSize = 2 * kPointerSize; | 2448 const int kFinallyStackSize = 2 * kPointerSize; |
| 2450 break_stack_height_ += kFinallyStackSize; | 2449 break_stack_height_ += kFinallyStackSize; |
| 2451 | 2450 |
| 2452 // Generate code for the statements in the finally block. | 2451 // Generate code for the statements in the finally block. |
| 2453 VisitStatementsAndSpill(node->finally_block()->statements()); | 2452 VisitStatementsAndSpill(node->finally_block()->statements()); |
| 2454 | 2453 |
| 2455 break_stack_height_ -= kFinallyStackSize; | 2454 break_stack_height_ -= kFinallyStackSize; |
| 2456 if (frame_ != NULL) { | 2455 if (has_valid_frame()) { |
| 2457 JumpTarget exit(this); | 2456 JumpTarget exit(this); |
| 2458 // Restore state and return value or faked TOS. | 2457 // Restore state and return value or faked TOS. |
| 2459 frame_->EmitPop(ecx); | 2458 frame_->EmitPop(ecx); |
| 2460 frame_->EmitPop(eax); | 2459 frame_->EmitPop(eax); |
| 2461 | 2460 |
| 2462 // Generate code to jump to the right destination for all used | 2461 // Generate code to jump to the right destination for all used |
| 2463 // (formerly) shadowing targets. | 2462 // (formerly) shadowing targets. |
| 2464 for (int i = 0; i <= nof_escapes; i++) { | 2463 for (int i = 0; i <= nof_escapes; i++) { |
| 2465 if (shadows[i]->is_bound()) { | 2464 if (shadows[i]->is_bound()) { |
| 2466 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); | 2465 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2526 | 2525 |
| 2527 | 2526 |
| 2528 void CodeGenerator::VisitConditional(Conditional* node) { | 2527 void CodeGenerator::VisitConditional(Conditional* node) { |
| 2529 VirtualFrame::SpilledScope spilled_scope(this); | 2528 VirtualFrame::SpilledScope spilled_scope(this); |
| 2530 Comment cmnt(masm_, "[ Conditional"); | 2529 Comment cmnt(masm_, "[ Conditional"); |
| 2531 JumpTarget then(this); | 2530 JumpTarget then(this); |
| 2532 JumpTarget else_(this); | 2531 JumpTarget else_(this); |
| 2533 JumpTarget exit(this); | 2532 JumpTarget exit(this); |
| 2534 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | 2533 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, |
| 2535 &then, &else_, true); | 2534 &then, &else_, true); |
| 2536 if (frame_ != NULL) { | 2535 if (has_valid_frame()) { |
| 2537 Branch(false, &else_); | 2536 Branch(false, &else_); |
| 2538 } | 2537 } |
| 2539 if (frame_ != NULL || then.is_linked()) { | 2538 if (has_valid_frame() || then.is_linked()) { |
| 2540 then.Bind(); | 2539 then.Bind(); |
| 2541 LoadAndSpill(node->then_expression(), typeof_state()); | 2540 LoadAndSpill(node->then_expression(), typeof_state()); |
| 2542 exit.Jump(); | 2541 exit.Jump(); |
| 2543 } | 2542 } |
| 2544 if (else_.is_linked()) { | 2543 if (else_.is_linked()) { |
| 2545 else_.Bind(); | 2544 else_.Bind(); |
| 2546 LoadAndSpill(node->else_expression(), typeof_state()); | 2545 LoadAndSpill(node->else_expression(), typeof_state()); |
| 2547 } | 2546 } |
| 2548 exit.Bind(); | 2547 exit.Bind(); |
| 2549 } | 2548 } |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2692 Expression* expr = var->rewrite(); | 2691 Expression* expr = var->rewrite(); |
| 2693 if (expr != NULL) { | 2692 if (expr != NULL) { |
| 2694 // We have to be wary of calling Visit directly on expressions. Because | 2693 // We have to be wary of calling Visit directly on expressions. Because |
| 2695 // of special casing comparisons of the form typeof<expr> === "string", | 2694 // of special casing comparisons of the form typeof<expr> === "string", |
| 2696 // we can return from a call from Visit (to a comparison or a unary | 2695 // we can return from a call from Visit (to a comparison or a unary |
| 2697 // operation) without a virtual frame; which will probably crash if we | 2696 // operation) without a virtual frame; which will probably crash if we |
| 2698 // try to emit frame code before reestablishing a frame. Here we're | 2697 // try to emit frame code before reestablishing a frame. Here we're |
| 2699 // safe as long as variable proxies can't rewrite into typeof | 2698 // safe as long as variable proxies can't rewrite into typeof |
| 2700 // comparisons or unary logical not expressions. | 2699 // comparisons or unary logical not expressions. |
| 2701 Visit(expr); | 2700 Visit(expr); |
| 2702 ASSERT(frame_ != NULL); | 2701 ASSERT(has_valid_frame()); |
| 2703 } else { | 2702 } else { |
| 2704 ASSERT(var->is_global()); | 2703 ASSERT(var->is_global()); |
| 2705 Reference ref(this, node); | 2704 Reference ref(this, node); |
| 2706 ref.GetValue(typeof_state()); | 2705 ref.GetValue(typeof_state()); |
| 2707 } | 2706 } |
| 2708 } | 2707 } |
| 2709 | 2708 |
| 2710 | 2709 |
| 2711 void CodeGenerator::VisitLiteral(Literal* node) { | 2710 void CodeGenerator::VisitLiteral(Literal* node) { |
| 2712 Comment cmnt(masm_, "[ Literal"); | 2711 Comment cmnt(masm_, "[ Literal"); |
| (...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3868 // after evaluating the left hand side (due to the shortcut | 3867 // after evaluating the left hand side (due to the shortcut |
| 3869 // semantics), but the compiler must (statically) know if the result | 3868 // semantics), but the compiler must (statically) know if the result |
| 3870 // of compiling the binary operation is materialized or not. | 3869 // of compiling the binary operation is materialized or not. |
| 3871 | 3870 |
| 3872 if (op == Token::AND) { | 3871 if (op == Token::AND) { |
| 3873 JumpTarget is_true(this); | 3872 JumpTarget is_true(this); |
| 3874 LoadConditionAndSpill(node->left(), NOT_INSIDE_TYPEOF, | 3873 LoadConditionAndSpill(node->left(), NOT_INSIDE_TYPEOF, |
| 3875 &is_true, false_target(), false); | 3874 &is_true, false_target(), false); |
| 3876 if (has_cc() || frame_ == NULL) { | 3875 if (has_cc() || frame_ == NULL) { |
| 3877 if (has_cc()) { | 3876 if (has_cc()) { |
| 3878 ASSERT(frame_ != NULL); | 3877 ASSERT(has_valid_frame()); |
| 3879 Branch(false, false_target()); | 3878 Branch(false, false_target()); |
| 3880 } | 3879 } |
| 3881 | 3880 |
| 3882 if (frame_ != NULL || is_true.is_linked()) { | 3881 if (has_valid_frame() || is_true.is_linked()) { |
| 3883 // Evaluate right side expression. | 3882 // Evaluate right side expression. |
| 3884 is_true.Bind(); | 3883 is_true.Bind(); |
| 3885 LoadConditionAndSpill(node->right(), NOT_INSIDE_TYPEOF, | 3884 LoadConditionAndSpill(node->right(), NOT_INSIDE_TYPEOF, |
| 3886 true_target(), false_target(), false); | 3885 true_target(), false_target(), false); |
| 3887 } | 3886 } |
| 3888 } else { | 3887 } else { |
| 3889 // We have a materialized value on the frame. | 3888 // We have a materialized value on the frame. |
| 3890 JumpTarget pop_and_continue(this); | 3889 JumpTarget pop_and_continue(this); |
| 3891 JumpTarget exit(this); | 3890 JumpTarget exit(this); |
| 3892 | 3891 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3911 // Exit (always with a materialized value). | 3910 // Exit (always with a materialized value). |
| 3912 exit.Bind(); | 3911 exit.Bind(); |
| 3913 } | 3912 } |
| 3914 | 3913 |
| 3915 } else if (op == Token::OR) { | 3914 } else if (op == Token::OR) { |
| 3916 JumpTarget is_false(this); | 3915 JumpTarget is_false(this); |
| 3917 LoadConditionAndSpill(node->left(), NOT_INSIDE_TYPEOF, | 3916 LoadConditionAndSpill(node->left(), NOT_INSIDE_TYPEOF, |
| 3918 true_target(), &is_false, false); | 3917 true_target(), &is_false, false); |
| 3919 if (has_cc() || frame_ == NULL) { | 3918 if (has_cc() || frame_ == NULL) { |
| 3920 if (has_cc()) { | 3919 if (has_cc()) { |
| 3921 ASSERT(frame_ != NULL); | 3920 ASSERT(has_valid_frame()); |
| 3922 Branch(true, true_target()); | 3921 Branch(true, true_target()); |
| 3923 } | 3922 } |
| 3924 | 3923 |
| 3925 if (frame_ != NULL || is_false.is_linked()) { | 3924 if (has_valid_frame() || is_false.is_linked()) { |
| 3926 // Evaluate right side expression. | 3925 // Evaluate right side expression. |
| 3927 is_false.Bind(); | 3926 is_false.Bind(); |
| 3928 LoadConditionAndSpill(node->right(), NOT_INSIDE_TYPEOF, | 3927 LoadConditionAndSpill(node->right(), NOT_INSIDE_TYPEOF, |
| 3929 true_target(), false_target(), false); | 3928 true_target(), false_target(), false); |
| 3930 } | 3929 } |
| 3931 | 3930 |
| 3932 } else { | 3931 } else { |
| 3933 // We have a materialized value on the frame. | 3932 // We have a materialized value on the frame. |
| 3934 JumpTarget pop_and_continue(this); | 3933 JumpTarget pop_and_continue(this); |
| 3935 JumpTarget exit(this); | 3934 JumpTarget exit(this); |
| (...skipping 1829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5765 | 5764 |
| 5766 // Slow-case: Go through the JavaScript implementation. | 5765 // Slow-case: Go through the JavaScript implementation. |
| 5767 __ bind(&slow); | 5766 __ bind(&slow); |
| 5768 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5767 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 5769 } | 5768 } |
| 5770 | 5769 |
| 5771 | 5770 |
| 5772 #undef __ | 5771 #undef __ |
| 5773 | 5772 |
| 5774 } } // namespace v8::internal | 5773 } } // namespace v8::internal |
| OLD | NEW |