| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 } | 85 } |
| 86 } | 86 } |
| 87 } | 87 } |
| 88 | 88 |
| 89 | 89 |
| 90 // ------------------------------------------------------------------------- | 90 // ------------------------------------------------------------------------- |
| 91 // CodeGenState implementation. | 91 // CodeGenState implementation. |
| 92 | 92 |
| 93 CodeGenState::CodeGenState(CodeGenerator* owner) | 93 CodeGenState::CodeGenState(CodeGenerator* owner) |
| 94 : owner_(owner), | 94 : owner_(owner), |
| 95 typeof_state_(NOT_INSIDE_TYPEOF), | |
| 96 true_target_(NULL), | 95 true_target_(NULL), |
| 97 false_target_(NULL), | 96 false_target_(NULL), |
| 98 previous_(NULL) { | 97 previous_(NULL) { |
| 99 owner_->set_state(this); | 98 owner_->set_state(this); |
| 100 } | 99 } |
| 101 | 100 |
| 102 | 101 |
| 103 CodeGenState::CodeGenState(CodeGenerator* owner, | 102 CodeGenState::CodeGenState(CodeGenerator* owner, |
| 104 TypeofState typeof_state, | |
| 105 JumpTarget* true_target, | 103 JumpTarget* true_target, |
| 106 JumpTarget* false_target) | 104 JumpTarget* false_target) |
| 107 : owner_(owner), | 105 : owner_(owner), |
| 108 typeof_state_(typeof_state), | |
| 109 true_target_(true_target), | 106 true_target_(true_target), |
| 110 false_target_(false_target), | 107 false_target_(false_target), |
| 111 previous_(owner->state()) { | 108 previous_(owner->state()) { |
| 112 owner_->set_state(this); | 109 owner_->set_state(this); |
| 113 } | 110 } |
| 114 | 111 |
| 115 | 112 |
| 116 CodeGenState::~CodeGenState() { | 113 CodeGenState::~CodeGenState() { |
| 117 ASSERT(owner_->state() == this); | 114 ASSERT(owner_->state() == this); |
| 118 owner_->set_state(previous_); | 115 owner_->set_state(previous_); |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 } | 435 } |
| 439 | 436 |
| 440 | 437 |
| 441 // Loads a value on TOS. If it is a boolean value, the result may have been | 438 // Loads a value on TOS. If it is a boolean value, the result may have been |
| 442 // (partially) translated into branches, or it may have set the condition | 439 // (partially) translated into branches, or it may have set the condition |
| 443 // code register. If force_cc is set, the value is forced to set the | 440 // code register. If force_cc is set, the value is forced to set the |
| 444 // condition code register and no value is pushed. If the condition code | 441 // condition code register and no value is pushed. If the condition code |
| 445 // register was set, has_cc() is true and cc_reg_ contains the condition to | 442 // register was set, has_cc() is true and cc_reg_ contains the condition to |
| 446 // test for 'true'. | 443 // test for 'true'. |
| 447 void CodeGenerator::LoadCondition(Expression* x, | 444 void CodeGenerator::LoadCondition(Expression* x, |
| 448 TypeofState typeof_state, | |
| 449 JumpTarget* true_target, | 445 JumpTarget* true_target, |
| 450 JumpTarget* false_target, | 446 JumpTarget* false_target, |
| 451 bool force_cc) { | 447 bool force_cc) { |
| 452 ASSERT(!has_cc()); | 448 ASSERT(!has_cc()); |
| 453 int original_height = frame_->height(); | 449 int original_height = frame_->height(); |
| 454 | 450 |
| 455 { CodeGenState new_state(this, typeof_state, true_target, false_target); | 451 { CodeGenState new_state(this, true_target, false_target); |
| 456 Visit(x); | 452 Visit(x); |
| 457 | 453 |
| 458 // If we hit a stack overflow, we may not have actually visited | 454 // If we hit a stack overflow, we may not have actually visited |
| 459 // the expression. In that case, we ensure that we have a | 455 // the expression. In that case, we ensure that we have a |
| 460 // valid-looking frame state because we will continue to generate | 456 // valid-looking frame state because we will continue to generate |
| 461 // code as we unwind the C++ stack. | 457 // code as we unwind the C++ stack. |
| 462 // | 458 // |
| 463 // It's possible to have both a stack overflow and a valid frame | 459 // It's possible to have both a stack overflow and a valid frame |
| 464 // state (eg, a subexpression overflowed, visiting it returned | 460 // state (eg, a subexpression overflowed, visiting it returned |
| 465 // with a dummied frame state, and visiting this expression | 461 // with a dummied frame state, and visiting this expression |
| 466 // returned with a normal-looking state). | 462 // returned with a normal-looking state). |
| 467 if (HasStackOverflow() && | 463 if (HasStackOverflow() && |
| 468 has_valid_frame() && | 464 has_valid_frame() && |
| 469 !has_cc() && | 465 !has_cc() && |
| 470 frame_->height() == original_height) { | 466 frame_->height() == original_height) { |
| 471 true_target->Jump(); | 467 true_target->Jump(); |
| 472 } | 468 } |
| 473 } | 469 } |
| 474 if (force_cc && frame_ != NULL && !has_cc()) { | 470 if (force_cc && frame_ != NULL && !has_cc()) { |
| 475 // Convert the TOS value to a boolean in the condition code register. | 471 // Convert the TOS value to a boolean in the condition code register. |
| 476 ToBoolean(true_target, false_target); | 472 ToBoolean(true_target, false_target); |
| 477 } | 473 } |
| 478 ASSERT(!force_cc || !has_valid_frame() || has_cc()); | 474 ASSERT(!force_cc || !has_valid_frame() || has_cc()); |
| 479 ASSERT(!has_valid_frame() || | 475 ASSERT(!has_valid_frame() || |
| 480 (has_cc() && frame_->height() == original_height) || | 476 (has_cc() && frame_->height() == original_height) || |
| 481 (!has_cc() && frame_->height() == original_height + 1)); | 477 (!has_cc() && frame_->height() == original_height + 1)); |
| 482 } | 478 } |
| 483 | 479 |
| 484 | 480 |
| 485 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { | 481 void CodeGenerator::Load(Expression* expr) { |
| 486 #ifdef DEBUG | 482 #ifdef DEBUG |
| 487 int original_height = frame_->height(); | 483 int original_height = frame_->height(); |
| 488 #endif | 484 #endif |
| 489 JumpTarget true_target; | 485 JumpTarget true_target; |
| 490 JumpTarget false_target; | 486 JumpTarget false_target; |
| 491 LoadCondition(x, typeof_state, &true_target, &false_target, false); | 487 LoadCondition(expr, &true_target, &false_target, false); |
| 492 | 488 |
| 493 if (has_cc()) { | 489 if (has_cc()) { |
| 494 // Convert cc_reg_ into a boolean value. | 490 // Convert cc_reg_ into a boolean value. |
| 495 JumpTarget loaded; | 491 JumpTarget loaded; |
| 496 JumpTarget materialize_true; | 492 JumpTarget materialize_true; |
| 497 materialize_true.Branch(cc_reg_); | 493 materialize_true.Branch(cc_reg_); |
| 498 __ LoadRoot(r0, Heap::kFalseValueRootIndex); | 494 __ LoadRoot(r0, Heap::kFalseValueRootIndex); |
| 499 frame_->EmitPush(r0); | 495 frame_->EmitPush(r0); |
| 500 loaded.Jump(); | 496 loaded.Jump(); |
| 501 materialize_true.Bind(); | 497 materialize_true.Bind(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 | 544 |
| 549 void CodeGenerator::LoadGlobalReceiver(Register scratch) { | 545 void CodeGenerator::LoadGlobalReceiver(Register scratch) { |
| 550 VirtualFrame::SpilledScope spilled_scope; | 546 VirtualFrame::SpilledScope spilled_scope; |
| 551 __ ldr(scratch, ContextOperand(cp, Context::GLOBAL_INDEX)); | 547 __ ldr(scratch, ContextOperand(cp, Context::GLOBAL_INDEX)); |
| 552 __ ldr(scratch, | 548 __ ldr(scratch, |
| 553 FieldMemOperand(scratch, GlobalObject::kGlobalReceiverOffset)); | 549 FieldMemOperand(scratch, GlobalObject::kGlobalReceiverOffset)); |
| 554 frame_->EmitPush(scratch); | 550 frame_->EmitPush(scratch); |
| 555 } | 551 } |
| 556 | 552 |
| 557 | 553 |
| 558 // TODO(1241834): Get rid of this function in favor of just using Load, now | 554 void CodeGenerator::LoadTypeofExpression(Expression* expr) { |
| 559 // that we have the INSIDE_TYPEOF typeof state. => Need to handle global | 555 // Special handling of identifiers as subexpressions of typeof. |
| 560 // variables w/o reference errors elsewhere. | |
| 561 void CodeGenerator::LoadTypeofExpression(Expression* x) { | |
| 562 VirtualFrame::SpilledScope spilled_scope; | 556 VirtualFrame::SpilledScope spilled_scope; |
| 563 Variable* variable = x->AsVariableProxy()->AsVariable(); | 557 Variable* variable = expr->AsVariableProxy()->AsVariable(); |
| 564 if (variable != NULL && !variable->is_this() && variable->is_global()) { | 558 if (variable != NULL && !variable->is_this() && variable->is_global()) { |
| 565 // NOTE: This is somewhat nasty. We force the compiler to load | 559 // For a global variable we build the property reference |
| 566 // the variable as if through '<global>.<variable>' to make sure we | 560 // <global>.<variable> and perform a (regular non-contextual) property |
| 567 // do not get reference errors. | 561 // load to make sure we do not get reference errors. |
| 568 Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX); | 562 Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX); |
| 569 Literal key(variable->name()); | 563 Literal key(variable->name()); |
| 570 // TODO(1241834): Fetch the position from the variable instead of using | 564 // TODO(1241834): Fetch the position from the variable instead of using |
| 571 // no position. | 565 // no position. |
| 572 Property property(&global, &key, RelocInfo::kNoPosition); | 566 Property property(&global, &key, RelocInfo::kNoPosition); |
| 573 LoadAndSpill(&property); | 567 Reference ref(this, &property); |
| 568 ref.GetValueAndSpill(); |
| 569 } else if (variable != NULL && variable->slot() != NULL) { |
| 570 // For a variable that rewrites to a slot, we signal it is the immediate |
| 571 // subexpression of a typeof. |
| 572 LoadFromSlot(variable->slot(), INSIDE_TYPEOF); |
| 573 frame_->SpillAll(); |
| 574 } else { | 574 } else { |
| 575 LoadAndSpill(x, INSIDE_TYPEOF); | 575 // Anything else can be handled normally. |
| 576 LoadAndSpill(expr); |
| 576 } | 577 } |
| 577 } | 578 } |
| 578 | 579 |
| 579 | 580 |
| 580 Reference::Reference(CodeGenerator* cgen, Expression* expression) | 581 Reference::Reference(CodeGenerator* cgen, Expression* expression) |
| 581 : cgen_(cgen), expression_(expression), type_(ILLEGAL) { | 582 : cgen_(cgen), expression_(expression), type_(ILLEGAL) { |
| 582 cgen->LoadReference(this); | 583 cgen->LoadReference(this); |
| 583 } | 584 } |
| 584 | 585 |
| 585 | 586 |
| (...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 bool has_else_stm = node->HasElseStatement(); | 1273 bool has_else_stm = node->HasElseStatement(); |
| 1273 | 1274 |
| 1274 CodeForStatementPosition(node); | 1275 CodeForStatementPosition(node); |
| 1275 | 1276 |
| 1276 JumpTarget exit; | 1277 JumpTarget exit; |
| 1277 if (has_then_stm && has_else_stm) { | 1278 if (has_then_stm && has_else_stm) { |
| 1278 Comment cmnt(masm_, "[ IfThenElse"); | 1279 Comment cmnt(masm_, "[ IfThenElse"); |
| 1279 JumpTarget then; | 1280 JumpTarget then; |
| 1280 JumpTarget else_; | 1281 JumpTarget else_; |
| 1281 // if (cond) | 1282 // if (cond) |
| 1282 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | 1283 LoadConditionAndSpill(node->condition(), &then, &else_, true); |
| 1283 &then, &else_, true); | |
| 1284 if (frame_ != NULL) { | 1284 if (frame_ != NULL) { |
| 1285 Branch(false, &else_); | 1285 Branch(false, &else_); |
| 1286 } | 1286 } |
| 1287 // then | 1287 // then |
| 1288 if (frame_ != NULL || then.is_linked()) { | 1288 if (frame_ != NULL || then.is_linked()) { |
| 1289 then.Bind(); | 1289 then.Bind(); |
| 1290 VisitAndSpill(node->then_statement()); | 1290 VisitAndSpill(node->then_statement()); |
| 1291 } | 1291 } |
| 1292 if (frame_ != NULL) { | 1292 if (frame_ != NULL) { |
| 1293 exit.Jump(); | 1293 exit.Jump(); |
| 1294 } | 1294 } |
| 1295 // else | 1295 // else |
| 1296 if (else_.is_linked()) { | 1296 if (else_.is_linked()) { |
| 1297 else_.Bind(); | 1297 else_.Bind(); |
| 1298 VisitAndSpill(node->else_statement()); | 1298 VisitAndSpill(node->else_statement()); |
| 1299 } | 1299 } |
| 1300 | 1300 |
| 1301 } else if (has_then_stm) { | 1301 } else if (has_then_stm) { |
| 1302 Comment cmnt(masm_, "[ IfThen"); | 1302 Comment cmnt(masm_, "[ IfThen"); |
| 1303 ASSERT(!has_else_stm); | 1303 ASSERT(!has_else_stm); |
| 1304 JumpTarget then; | 1304 JumpTarget then; |
| 1305 // if (cond) | 1305 // if (cond) |
| 1306 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | 1306 LoadConditionAndSpill(node->condition(), &then, &exit, true); |
| 1307 &then, &exit, true); | |
| 1308 if (frame_ != NULL) { | 1307 if (frame_ != NULL) { |
| 1309 Branch(false, &exit); | 1308 Branch(false, &exit); |
| 1310 } | 1309 } |
| 1311 // then | 1310 // then |
| 1312 if (frame_ != NULL || then.is_linked()) { | 1311 if (frame_ != NULL || then.is_linked()) { |
| 1313 then.Bind(); | 1312 then.Bind(); |
| 1314 VisitAndSpill(node->then_statement()); | 1313 VisitAndSpill(node->then_statement()); |
| 1315 } | 1314 } |
| 1316 | 1315 |
| 1317 } else if (has_else_stm) { | 1316 } else if (has_else_stm) { |
| 1318 Comment cmnt(masm_, "[ IfElse"); | 1317 Comment cmnt(masm_, "[ IfElse"); |
| 1319 ASSERT(!has_then_stm); | 1318 ASSERT(!has_then_stm); |
| 1320 JumpTarget else_; | 1319 JumpTarget else_; |
| 1321 // if (!cond) | 1320 // if (!cond) |
| 1322 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | 1321 LoadConditionAndSpill(node->condition(), &exit, &else_, true); |
| 1323 &exit, &else_, true); | |
| 1324 if (frame_ != NULL) { | 1322 if (frame_ != NULL) { |
| 1325 Branch(true, &exit); | 1323 Branch(true, &exit); |
| 1326 } | 1324 } |
| 1327 // else | 1325 // else |
| 1328 if (frame_ != NULL || else_.is_linked()) { | 1326 if (frame_ != NULL || else_.is_linked()) { |
| 1329 else_.Bind(); | 1327 else_.Bind(); |
| 1330 VisitAndSpill(node->else_statement()); | 1328 VisitAndSpill(node->else_statement()); |
| 1331 } | 1329 } |
| 1332 | 1330 |
| 1333 } else { | 1331 } else { |
| 1334 Comment cmnt(masm_, "[ If"); | 1332 Comment cmnt(masm_, "[ If"); |
| 1335 ASSERT(!has_then_stm && !has_else_stm); | 1333 ASSERT(!has_then_stm && !has_else_stm); |
| 1336 // if (cond) | 1334 // if (cond) |
| 1337 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | 1335 LoadConditionAndSpill(node->condition(), &exit, &exit, false); |
| 1338 &exit, &exit, false); | |
| 1339 if (frame_ != NULL) { | 1336 if (frame_ != NULL) { |
| 1340 if (has_cc()) { | 1337 if (has_cc()) { |
| 1341 cc_reg_ = al; | 1338 cc_reg_ = al; |
| 1342 } else { | 1339 } else { |
| 1343 frame_->Drop(); | 1340 frame_->Drop(); |
| 1344 } | 1341 } |
| 1345 } | 1342 } |
| 1346 } | 1343 } |
| 1347 | 1344 |
| 1348 // end | 1345 // end |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1566 node->continue_target()->Bind(); | 1563 node->continue_target()->Bind(); |
| 1567 } | 1564 } |
| 1568 break; | 1565 break; |
| 1569 case DONT_KNOW: | 1566 case DONT_KNOW: |
| 1570 // We have to compile the test expression if it can be reached by | 1567 // We have to compile the test expression if it can be reached by |
| 1571 // control flow falling out of the body or via continue. | 1568 // control flow falling out of the body or via continue. |
| 1572 if (node->continue_target()->is_linked()) { | 1569 if (node->continue_target()->is_linked()) { |
| 1573 node->continue_target()->Bind(); | 1570 node->continue_target()->Bind(); |
| 1574 } | 1571 } |
| 1575 if (has_valid_frame()) { | 1572 if (has_valid_frame()) { |
| 1576 LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF, | 1573 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true); |
| 1577 &body, node->break_target(), true); | |
| 1578 if (has_valid_frame()) { | 1574 if (has_valid_frame()) { |
| 1579 // A invalid frame here indicates that control did not | 1575 // A invalid frame here indicates that control did not |
| 1580 // fall out of the test expression. | 1576 // fall out of the test expression. |
| 1581 Branch(true, &body); | 1577 Branch(true, &body); |
| 1582 } | 1578 } |
| 1583 } | 1579 } |
| 1584 break; | 1580 break; |
| 1585 } | 1581 } |
| 1586 | 1582 |
| 1587 if (node->break_target()->is_linked()) { | 1583 if (node->break_target()->is_linked()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1606 | 1602 |
| 1607 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); | 1603 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); |
| 1608 | 1604 |
| 1609 // Label the top of the loop with the continue target for the backward | 1605 // Label the top of the loop with the continue target for the backward |
| 1610 // CFG edge. | 1606 // CFG edge. |
| 1611 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL); | 1607 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL); |
| 1612 node->continue_target()->Bind(); | 1608 node->continue_target()->Bind(); |
| 1613 | 1609 |
| 1614 if (info == DONT_KNOW) { | 1610 if (info == DONT_KNOW) { |
| 1615 JumpTarget body; | 1611 JumpTarget body; |
| 1616 LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF, | 1612 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true); |
| 1617 &body, node->break_target(), true); | |
| 1618 if (has_valid_frame()) { | 1613 if (has_valid_frame()) { |
| 1619 // A NULL frame indicates that control did not fall out of the | 1614 // A NULL frame indicates that control did not fall out of the |
| 1620 // test expression. | 1615 // test expression. |
| 1621 Branch(false, node->break_target()); | 1616 Branch(false, node->break_target()); |
| 1622 } | 1617 } |
| 1623 if (has_valid_frame() || body.is_linked()) { | 1618 if (has_valid_frame() || body.is_linked()) { |
| 1624 body.Bind(); | 1619 body.Bind(); |
| 1625 } | 1620 } |
| 1626 } | 1621 } |
| 1627 | 1622 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1666 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL); | 1661 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL); |
| 1667 node->continue_target()->Bind(); | 1662 node->continue_target()->Bind(); |
| 1668 } else { | 1663 } else { |
| 1669 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); | 1664 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); |
| 1670 loop.Bind(); | 1665 loop.Bind(); |
| 1671 } | 1666 } |
| 1672 | 1667 |
| 1673 // If the test is always true, there is no need to compile it. | 1668 // If the test is always true, there is no need to compile it. |
| 1674 if (info == DONT_KNOW) { | 1669 if (info == DONT_KNOW) { |
| 1675 JumpTarget body; | 1670 JumpTarget body; |
| 1676 LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF, | 1671 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true); |
| 1677 &body, node->break_target(), true); | |
| 1678 if (has_valid_frame()) { | 1672 if (has_valid_frame()) { |
| 1679 Branch(false, node->break_target()); | 1673 Branch(false, node->break_target()); |
| 1680 } | 1674 } |
| 1681 if (has_valid_frame() || body.is_linked()) { | 1675 if (has_valid_frame() || body.is_linked()) { |
| 1682 body.Bind(); | 1676 body.Bind(); |
| 1683 } | 1677 } |
| 1684 } | 1678 } |
| 1685 | 1679 |
| 1686 if (has_valid_frame()) { | 1680 if (has_valid_frame()) { |
| 1687 CheckStack(); // TODO(1222600): ignore if body contains calls. | 1681 CheckStack(); // TODO(1222600): ignore if body contains calls. |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2276 | 2270 |
| 2277 | 2271 |
| 2278 void CodeGenerator::VisitConditional(Conditional* node) { | 2272 void CodeGenerator::VisitConditional(Conditional* node) { |
| 2279 #ifdef DEBUG | 2273 #ifdef DEBUG |
| 2280 int original_height = frame_->height(); | 2274 int original_height = frame_->height(); |
| 2281 #endif | 2275 #endif |
| 2282 VirtualFrame::SpilledScope spilled_scope; | 2276 VirtualFrame::SpilledScope spilled_scope; |
| 2283 Comment cmnt(masm_, "[ Conditional"); | 2277 Comment cmnt(masm_, "[ Conditional"); |
| 2284 JumpTarget then; | 2278 JumpTarget then; |
| 2285 JumpTarget else_; | 2279 JumpTarget else_; |
| 2286 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | 2280 LoadConditionAndSpill(node->condition(), &then, &else_, true); |
| 2287 &then, &else_, true); | |
| 2288 if (has_valid_frame()) { | 2281 if (has_valid_frame()) { |
| 2289 Branch(false, &else_); | 2282 Branch(false, &else_); |
| 2290 } | 2283 } |
| 2291 if (has_valid_frame() || then.is_linked()) { | 2284 if (has_valid_frame() || then.is_linked()) { |
| 2292 then.Bind(); | 2285 then.Bind(); |
| 2293 LoadAndSpill(node->then_expression(), typeof_state()); | 2286 LoadAndSpill(node->then_expression()); |
| 2294 } | 2287 } |
| 2295 if (else_.is_linked()) { | 2288 if (else_.is_linked()) { |
| 2296 JumpTarget exit; | 2289 JumpTarget exit; |
| 2297 if (has_valid_frame()) exit.Jump(); | 2290 if (has_valid_frame()) exit.Jump(); |
| 2298 else_.Bind(); | 2291 else_.Bind(); |
| 2299 LoadAndSpill(node->else_expression(), typeof_state()); | 2292 LoadAndSpill(node->else_expression()); |
| 2300 if (exit.is_linked()) exit.Bind(); | 2293 if (exit.is_linked()) exit.Bind(); |
| 2301 } | 2294 } |
| 2302 ASSERT(frame_->height() == original_height + 1); | 2295 ASSERT(frame_->height() == original_height + 1); |
| 2303 } | 2296 } |
| 2304 | 2297 |
| 2305 | 2298 |
| 2306 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { | 2299 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
| 2307 VirtualFrame::SpilledScope spilled_scope; | 2300 VirtualFrame::SpilledScope spilled_scope; |
| 2308 if (slot->type() == Slot::LOOKUP) { | 2301 if (slot->type() == Slot::LOOKUP) { |
| 2309 ASSERT(slot->var()->is_dynamic()); | 2302 ASSERT(slot->var()->is_dynamic()); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2356 if (typeof_state == INSIDE_TYPEOF) { | 2349 if (typeof_state == INSIDE_TYPEOF) { |
| 2357 frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 2350 frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
| 2358 } else { | 2351 } else { |
| 2359 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); | 2352 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); |
| 2360 } | 2353 } |
| 2361 | 2354 |
| 2362 done.Bind(); | 2355 done.Bind(); |
| 2363 frame_->EmitPush(r0); | 2356 frame_->EmitPush(r0); |
| 2364 | 2357 |
| 2365 } else { | 2358 } else { |
| 2366 // Note: We would like to keep the assert below, but it fires because of | |
| 2367 // some nasty code in LoadTypeofExpression() which should be removed... | |
| 2368 // ASSERT(!slot->var()->is_dynamic()); | |
| 2369 | |
| 2370 // Special handling for locals allocated in registers. | 2359 // Special handling for locals allocated in registers. |
| 2371 __ ldr(r0, SlotOperand(slot, r2)); | 2360 __ ldr(r0, SlotOperand(slot, r2)); |
| 2372 frame_->EmitPush(r0); | 2361 frame_->EmitPush(r0); |
| 2373 if (slot->var()->mode() == Variable::CONST) { | 2362 if (slot->var()->mode() == Variable::CONST) { |
| 2374 // Const slots may contain 'the hole' value (the constant hasn't been | 2363 // Const slots may contain 'the hole' value (the constant hasn't been |
| 2375 // initialized yet) which needs to be converted into the 'undefined' | 2364 // initialized yet) which needs to be converted into the 'undefined' |
| 2376 // value. | 2365 // value. |
| 2377 Comment cmnt(masm_, "[ Unhole const"); | 2366 Comment cmnt(masm_, "[ Unhole const"); |
| 2378 frame_->EmitPop(r0); | 2367 frame_->EmitPop(r0); |
| 2379 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2368 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2454 frame_->Drop(); | 2443 frame_->Drop(); |
| 2455 } | 2444 } |
| 2456 | 2445 |
| 2457 | 2446 |
| 2458 void CodeGenerator::VisitSlot(Slot* node) { | 2447 void CodeGenerator::VisitSlot(Slot* node) { |
| 2459 #ifdef DEBUG | 2448 #ifdef DEBUG |
| 2460 int original_height = frame_->height(); | 2449 int original_height = frame_->height(); |
| 2461 #endif | 2450 #endif |
| 2462 VirtualFrame::SpilledScope spilled_scope; | 2451 VirtualFrame::SpilledScope spilled_scope; |
| 2463 Comment cmnt(masm_, "[ Slot"); | 2452 Comment cmnt(masm_, "[ Slot"); |
| 2464 LoadFromSlot(node, typeof_state()); | 2453 LoadFromSlot(node, NOT_INSIDE_TYPEOF); |
| 2465 ASSERT(frame_->height() == original_height + 1); | 2454 ASSERT(frame_->height() == original_height + 1); |
| 2466 } | 2455 } |
| 2467 | 2456 |
| 2468 | 2457 |
| 2469 void CodeGenerator::VisitVariableProxy(VariableProxy* node) { | 2458 void CodeGenerator::VisitVariableProxy(VariableProxy* node) { |
| 2470 #ifdef DEBUG | 2459 #ifdef DEBUG |
| 2471 int original_height = frame_->height(); | 2460 int original_height = frame_->height(); |
| 2472 #endif | 2461 #endif |
| 2473 VirtualFrame::SpilledScope spilled_scope; | 2462 VirtualFrame::SpilledScope spilled_scope; |
| 2474 Comment cmnt(masm_, "[ VariableProxy"); | 2463 Comment cmnt(masm_, "[ VariableProxy"); |
| 2475 | 2464 |
| 2476 Variable* var = node->var(); | 2465 Variable* var = node->var(); |
| 2477 Expression* expr = var->rewrite(); | 2466 Expression* expr = var->rewrite(); |
| 2478 if (expr != NULL) { | 2467 if (expr != NULL) { |
| 2479 Visit(expr); | 2468 Visit(expr); |
| 2480 } else { | 2469 } else { |
| 2481 ASSERT(var->is_global()); | 2470 ASSERT(var->is_global()); |
| 2482 Reference ref(this, node); | 2471 Reference ref(this, node); |
| 2483 ref.GetValueAndSpill(typeof_state()); | 2472 ref.GetValueAndSpill(); |
| 2484 } | 2473 } |
| 2485 ASSERT(frame_->height() == original_height + 1); | 2474 ASSERT(frame_->height() == original_height + 1); |
| 2486 } | 2475 } |
| 2487 | 2476 |
| 2488 | 2477 |
| 2489 void CodeGenerator::VisitLiteral(Literal* node) { | 2478 void CodeGenerator::VisitLiteral(Literal* node) { |
| 2490 #ifdef DEBUG | 2479 #ifdef DEBUG |
| 2491 int original_height = frame_->height(); | 2480 int original_height = frame_->height(); |
| 2492 #endif | 2481 #endif |
| 2493 VirtualFrame::SpilledScope spilled_scope; | 2482 VirtualFrame::SpilledScope spilled_scope; |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2809 } | 2798 } |
| 2810 | 2799 |
| 2811 if (node->op() == Token::ASSIGN || | 2800 if (node->op() == Token::ASSIGN || |
| 2812 node->op() == Token::INIT_VAR || | 2801 node->op() == Token::INIT_VAR || |
| 2813 node->op() == Token::INIT_CONST) { | 2802 node->op() == Token::INIT_CONST) { |
| 2814 LoadAndSpill(node->value()); | 2803 LoadAndSpill(node->value()); |
| 2815 | 2804 |
| 2816 } else { | 2805 } else { |
| 2817 // +=, *= and similar binary assignments. | 2806 // +=, *= and similar binary assignments. |
| 2818 // Get the old value of the lhs. | 2807 // Get the old value of the lhs. |
| 2819 target.GetValueAndSpill(NOT_INSIDE_TYPEOF); | 2808 target.GetValueAndSpill(); |
| 2820 Literal* literal = node->value()->AsLiteral(); | 2809 Literal* literal = node->value()->AsLiteral(); |
| 2821 bool overwrite = | 2810 bool overwrite = |
| 2822 (node->value()->AsBinaryOperation() != NULL && | 2811 (node->value()->AsBinaryOperation() != NULL && |
| 2823 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); | 2812 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); |
| 2824 if (literal != NULL && literal->handle()->IsSmi()) { | 2813 if (literal != NULL && literal->handle()->IsSmi()) { |
| 2825 SmiOperation(node->binary_op(), | 2814 SmiOperation(node->binary_op(), |
| 2826 literal->handle(), | 2815 literal->handle(), |
| 2827 false, | 2816 false, |
| 2828 overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE); | 2817 overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE); |
| 2829 frame_->EmitPush(r0); | 2818 frame_->EmitPush(r0); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2874 | 2863 |
| 2875 | 2864 |
| 2876 void CodeGenerator::VisitProperty(Property* node) { | 2865 void CodeGenerator::VisitProperty(Property* node) { |
| 2877 #ifdef DEBUG | 2866 #ifdef DEBUG |
| 2878 int original_height = frame_->height(); | 2867 int original_height = frame_->height(); |
| 2879 #endif | 2868 #endif |
| 2880 VirtualFrame::SpilledScope spilled_scope; | 2869 VirtualFrame::SpilledScope spilled_scope; |
| 2881 Comment cmnt(masm_, "[ Property"); | 2870 Comment cmnt(masm_, "[ Property"); |
| 2882 | 2871 |
| 2883 { Reference property(this, node); | 2872 { Reference property(this, node); |
| 2884 property.GetValueAndSpill(typeof_state()); | 2873 property.GetValueAndSpill(); |
| 2885 } | 2874 } |
| 2886 ASSERT(frame_->height() == original_height + 1); | 2875 ASSERT(frame_->height() == original_height + 1); |
| 2887 } | 2876 } |
| 2888 | 2877 |
| 2889 | 2878 |
| 2890 void CodeGenerator::VisitCall(Call* node) { | 2879 void CodeGenerator::VisitCall(Call* node) { |
| 2891 #ifdef DEBUG | 2880 #ifdef DEBUG |
| 2892 int original_height = frame_->height(); | 2881 int original_height = frame_->height(); |
| 2893 #endif | 2882 #endif |
| 2894 VirtualFrame::SpilledScope spilled_scope; | 2883 VirtualFrame::SpilledScope spilled_scope; |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3044 | 3033 |
| 3045 frame_->EmitPush(r0); // push after get rid of function from the stack | 3034 frame_->EmitPush(r0); // push after get rid of function from the stack |
| 3046 | 3035 |
| 3047 } else { | 3036 } else { |
| 3048 // ------------------------------------------- | 3037 // ------------------------------------------- |
| 3049 // JavaScript example: 'array[index](1, 2, 3)' | 3038 // JavaScript example: 'array[index](1, 2, 3)' |
| 3050 // ------------------------------------------- | 3039 // ------------------------------------------- |
| 3051 | 3040 |
| 3052 // Load the function to call from the property through a reference. | 3041 // Load the function to call from the property through a reference. |
| 3053 Reference ref(this, property); | 3042 Reference ref(this, property); |
| 3054 ref.GetValueAndSpill(NOT_INSIDE_TYPEOF); // receiver | 3043 ref.GetValueAndSpill(); // receiver |
| 3055 | 3044 |
| 3056 // Pass receiver to called function. | 3045 // Pass receiver to called function. |
| 3057 if (property->is_synthetic()) { | 3046 if (property->is_synthetic()) { |
| 3058 LoadGlobalReceiver(r0); | 3047 LoadGlobalReceiver(r0); |
| 3059 } else { | 3048 } else { |
| 3060 __ ldr(r0, frame_->ElementAt(ref.size())); | 3049 __ ldr(r0, frame_->ElementAt(ref.size())); |
| 3061 frame_->EmitPush(r0); | 3050 frame_->EmitPush(r0); |
| 3062 } | 3051 } |
| 3063 | 3052 |
| 3064 // Call the function. | 3053 // Call the function. |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3449 #ifdef DEBUG | 3438 #ifdef DEBUG |
| 3450 int original_height = frame_->height(); | 3439 int original_height = frame_->height(); |
| 3451 #endif | 3440 #endif |
| 3452 VirtualFrame::SpilledScope spilled_scope; | 3441 VirtualFrame::SpilledScope spilled_scope; |
| 3453 Comment cmnt(masm_, "[ UnaryOperation"); | 3442 Comment cmnt(masm_, "[ UnaryOperation"); |
| 3454 | 3443 |
| 3455 Token::Value op = node->op(); | 3444 Token::Value op = node->op(); |
| 3456 | 3445 |
| 3457 if (op == Token::NOT) { | 3446 if (op == Token::NOT) { |
| 3458 LoadConditionAndSpill(node->expression(), | 3447 LoadConditionAndSpill(node->expression(), |
| 3459 NOT_INSIDE_TYPEOF, | |
| 3460 false_target(), | 3448 false_target(), |
| 3461 true_target(), | 3449 true_target(), |
| 3462 true); | 3450 true); |
| 3463 // LoadCondition may (and usually does) leave a test and branch to | 3451 // LoadCondition may (and usually does) leave a test and branch to |
| 3464 // be emitted by the caller. In that case, negate the condition. | 3452 // be emitted by the caller. In that case, negate the condition. |
| 3465 if (has_cc()) cc_reg_ = NegateCondition(cc_reg_); | 3453 if (has_cc()) cc_reg_ = NegateCondition(cc_reg_); |
| 3466 | 3454 |
| 3467 } else if (op == Token::DELETE) { | 3455 } else if (op == Token::DELETE) { |
| 3468 Property* property = node->expression()->AsProperty(); | 3456 Property* property = node->expression()->AsProperty(); |
| 3469 Variable* variable = node->expression()->AsVariableProxy()->AsVariable(); | 3457 Variable* variable = node->expression()->AsVariableProxy()->AsVariable(); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3610 if (target.is_illegal()) { | 3598 if (target.is_illegal()) { |
| 3611 // Spoof the virtual frame to have the expected height (one higher | 3599 // Spoof the virtual frame to have the expected height (one higher |
| 3612 // than on entry). | 3600 // than on entry). |
| 3613 if (!is_postfix) { | 3601 if (!is_postfix) { |
| 3614 __ mov(r0, Operand(Smi::FromInt(0))); | 3602 __ mov(r0, Operand(Smi::FromInt(0))); |
| 3615 frame_->EmitPush(r0); | 3603 frame_->EmitPush(r0); |
| 3616 } | 3604 } |
| 3617 ASSERT(frame_->height() == original_height + 1); | 3605 ASSERT(frame_->height() == original_height + 1); |
| 3618 return; | 3606 return; |
| 3619 } | 3607 } |
| 3620 target.GetValueAndSpill(NOT_INSIDE_TYPEOF); | 3608 target.GetValueAndSpill(); |
| 3621 frame_->EmitPop(r0); | 3609 frame_->EmitPop(r0); |
| 3622 | 3610 |
| 3623 JumpTarget slow; | 3611 JumpTarget slow; |
| 3624 JumpTarget exit; | 3612 JumpTarget exit; |
| 3625 | 3613 |
| 3626 // Load the value (1) into register r1. | 3614 // Load the value (1) into register r1. |
| 3627 __ mov(r1, Operand(Smi::FromInt(1))); | 3615 __ mov(r1, Operand(Smi::FromInt(1))); |
| 3628 | 3616 |
| 3629 // Check for smi operand. | 3617 // Check for smi operand. |
| 3630 __ tst(r0, Operand(kSmiTagMask)); | 3618 __ tst(r0, Operand(kSmiTagMask)); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3704 // NOTE: If the left hand side produces a materialized value (not in | 3692 // NOTE: If the left hand side produces a materialized value (not in |
| 3705 // the CC register), we force the right hand side to do the | 3693 // the CC register), we force the right hand side to do the |
| 3706 // same. This is necessary because we may have to branch to the exit | 3694 // same. This is necessary because we may have to branch to the exit |
| 3707 // after evaluating the left hand side (due to the shortcut | 3695 // after evaluating the left hand side (due to the shortcut |
| 3708 // semantics), but the compiler must (statically) know if the result | 3696 // semantics), but the compiler must (statically) know if the result |
| 3709 // of compiling the binary operation is materialized or not. | 3697 // of compiling the binary operation is materialized or not. |
| 3710 | 3698 |
| 3711 if (op == Token::AND) { | 3699 if (op == Token::AND) { |
| 3712 JumpTarget is_true; | 3700 JumpTarget is_true; |
| 3713 LoadConditionAndSpill(node->left(), | 3701 LoadConditionAndSpill(node->left(), |
| 3714 NOT_INSIDE_TYPEOF, | |
| 3715 &is_true, | 3702 &is_true, |
| 3716 false_target(), | 3703 false_target(), |
| 3717 false); | 3704 false); |
| 3718 if (has_valid_frame() && !has_cc()) { | 3705 if (has_valid_frame() && !has_cc()) { |
| 3719 // The left-hand side result is on top of the virtual frame. | 3706 // The left-hand side result is on top of the virtual frame. |
| 3720 JumpTarget pop_and_continue; | 3707 JumpTarget pop_and_continue; |
| 3721 JumpTarget exit; | 3708 JumpTarget exit; |
| 3722 | 3709 |
| 3723 __ ldr(r0, frame_->Top()); // Duplicate the stack top. | 3710 __ ldr(r0, frame_->Top()); // Duplicate the stack top. |
| 3724 frame_->EmitPush(r0); | 3711 frame_->EmitPush(r0); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3740 exit.Bind(); | 3727 exit.Bind(); |
| 3741 } else if (has_cc() || is_true.is_linked()) { | 3728 } else if (has_cc() || is_true.is_linked()) { |
| 3742 // The left-hand side is either (a) partially compiled to | 3729 // The left-hand side is either (a) partially compiled to |
| 3743 // control flow with a final branch left to emit or (b) fully | 3730 // control flow with a final branch left to emit or (b) fully |
| 3744 // compiled to control flow and possibly true. | 3731 // compiled to control flow and possibly true. |
| 3745 if (has_cc()) { | 3732 if (has_cc()) { |
| 3746 Branch(false, false_target()); | 3733 Branch(false, false_target()); |
| 3747 } | 3734 } |
| 3748 is_true.Bind(); | 3735 is_true.Bind(); |
| 3749 LoadConditionAndSpill(node->right(), | 3736 LoadConditionAndSpill(node->right(), |
| 3750 NOT_INSIDE_TYPEOF, | |
| 3751 true_target(), | 3737 true_target(), |
| 3752 false_target(), | 3738 false_target(), |
| 3753 false); | 3739 false); |
| 3754 } else { | 3740 } else { |
| 3755 // Nothing to do. | 3741 // Nothing to do. |
| 3756 ASSERT(!has_valid_frame() && !has_cc() && !is_true.is_linked()); | 3742 ASSERT(!has_valid_frame() && !has_cc() && !is_true.is_linked()); |
| 3757 } | 3743 } |
| 3758 | 3744 |
| 3759 } else if (op == Token::OR) { | 3745 } else if (op == Token::OR) { |
| 3760 JumpTarget is_false; | 3746 JumpTarget is_false; |
| 3761 LoadConditionAndSpill(node->left(), | 3747 LoadConditionAndSpill(node->left(), |
| 3762 NOT_INSIDE_TYPEOF, | |
| 3763 true_target(), | 3748 true_target(), |
| 3764 &is_false, | 3749 &is_false, |
| 3765 false); | 3750 false); |
| 3766 if (has_valid_frame() && !has_cc()) { | 3751 if (has_valid_frame() && !has_cc()) { |
| 3767 // The left-hand side result is on top of the virtual frame. | 3752 // The left-hand side result is on top of the virtual frame. |
| 3768 JumpTarget pop_and_continue; | 3753 JumpTarget pop_and_continue; |
| 3769 JumpTarget exit; | 3754 JumpTarget exit; |
| 3770 | 3755 |
| 3771 __ ldr(r0, frame_->Top()); | 3756 __ ldr(r0, frame_->Top()); |
| 3772 frame_->EmitPush(r0); | 3757 frame_->EmitPush(r0); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3788 exit.Bind(); | 3773 exit.Bind(); |
| 3789 } else if (has_cc() || is_false.is_linked()) { | 3774 } else if (has_cc() || is_false.is_linked()) { |
| 3790 // The left-hand side is either (a) partially compiled to | 3775 // The left-hand side is either (a) partially compiled to |
| 3791 // control flow with a final branch left to emit or (b) fully | 3776 // control flow with a final branch left to emit or (b) fully |
| 3792 // compiled to control flow and possibly false. | 3777 // compiled to control flow and possibly false. |
| 3793 if (has_cc()) { | 3778 if (has_cc()) { |
| 3794 Branch(true, true_target()); | 3779 Branch(true, true_target()); |
| 3795 } | 3780 } |
| 3796 is_false.Bind(); | 3781 is_false.Bind(); |
| 3797 LoadConditionAndSpill(node->right(), | 3782 LoadConditionAndSpill(node->right(), |
| 3798 NOT_INSIDE_TYPEOF, | |
| 3799 true_target(), | 3783 true_target(), |
| 3800 false_target(), | 3784 false_target(), |
| 3801 false); | 3785 false); |
| 3802 } else { | 3786 } else { |
| 3803 // Nothing to do. | 3787 // Nothing to do. |
| 3804 ASSERT(!has_valid_frame() && !has_cc() && !is_false.is_linked()); | 3788 ASSERT(!has_valid_frame() && !has_cc() && !is_false.is_linked()); |
| 3805 } | 3789 } |
| 3806 | 3790 |
| 3807 } else { | 3791 } else { |
| 3808 // Optimize for the case where (at least) one of the expressions | 3792 // Optimize for the case where (at least) one of the expressions |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4087 ASSERT(proxy->AsVariable()->is_global()); | 4071 ASSERT(proxy->AsVariable()->is_global()); |
| 4088 return proxy->name(); | 4072 return proxy->name(); |
| 4089 } else { | 4073 } else { |
| 4090 Literal* raw_name = property->key()->AsLiteral(); | 4074 Literal* raw_name = property->key()->AsLiteral(); |
| 4091 ASSERT(raw_name != NULL); | 4075 ASSERT(raw_name != NULL); |
| 4092 return Handle<String>(String::cast(*raw_name->handle())); | 4076 return Handle<String>(String::cast(*raw_name->handle())); |
| 4093 } | 4077 } |
| 4094 } | 4078 } |
| 4095 | 4079 |
| 4096 | 4080 |
| 4097 void Reference::GetValue(TypeofState typeof_state) { | 4081 void Reference::GetValue() { |
| 4098 ASSERT(cgen_->HasValidEntryRegisters()); | 4082 ASSERT(cgen_->HasValidEntryRegisters()); |
| 4099 ASSERT(!is_illegal()); | 4083 ASSERT(!is_illegal()); |
| 4100 ASSERT(!cgen_->has_cc()); | 4084 ASSERT(!cgen_->has_cc()); |
| 4101 MacroAssembler* masm = cgen_->masm(); | 4085 MacroAssembler* masm = cgen_->masm(); |
| 4102 Property* property = expression_->AsProperty(); | 4086 Property* property = expression_->AsProperty(); |
| 4103 if (property != NULL) { | 4087 if (property != NULL) { |
| 4104 cgen_->CodeForSourcePosition(property->position()); | 4088 cgen_->CodeForSourcePosition(property->position()); |
| 4105 } | 4089 } |
| 4106 | 4090 |
| 4107 switch (type_) { | 4091 switch (type_) { |
| 4108 case SLOT: { | 4092 case SLOT: { |
| 4109 Comment cmnt(masm, "[ Load from Slot"); | 4093 Comment cmnt(masm, "[ Load from Slot"); |
| 4110 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); | 4094 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); |
| 4111 ASSERT(slot != NULL); | 4095 ASSERT(slot != NULL); |
| 4112 cgen_->LoadFromSlot(slot, typeof_state); | 4096 cgen_->LoadFromSlot(slot, NOT_INSIDE_TYPEOF); |
| 4113 break; | 4097 break; |
| 4114 } | 4098 } |
| 4115 | 4099 |
| 4116 case NAMED: { | 4100 case NAMED: { |
| 4117 // TODO(1241834): Make sure that this it is safe to ignore the | |
| 4118 // distinction between expressions in a typeof and not in a typeof. If | |
| 4119 // there is a chance that reference errors can be thrown below, we | |
| 4120 // must distinguish between the two kinds of loads (typeof expression | |
| 4121 // loads must not throw a reference error). | |
| 4122 VirtualFrame* frame = cgen_->frame(); | 4101 VirtualFrame* frame = cgen_->frame(); |
| 4123 Comment cmnt(masm, "[ Load from named Property"); | 4102 Comment cmnt(masm, "[ Load from named Property"); |
| 4124 Handle<String> name(GetName()); | 4103 Handle<String> name(GetName()); |
| 4125 Variable* var = expression_->AsVariableProxy()->AsVariable(); | 4104 Variable* var = expression_->AsVariableProxy()->AsVariable(); |
| 4126 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 4105 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 4127 // Setup the name register. | 4106 // Setup the name register. |
| 4128 Result name_reg(r2); | 4107 Result name_reg(r2); |
| 4129 __ mov(r2, Operand(name)); | 4108 __ mov(r2, Operand(name)); |
| 4130 ASSERT(var == NULL || var->is_global()); | 4109 ASSERT(var == NULL || var->is_global()); |
| 4131 RelocInfo::Mode rmode = (var == NULL) | 4110 RelocInfo::Mode rmode = (var == NULL) |
| 4132 ? RelocInfo::CODE_TARGET | 4111 ? RelocInfo::CODE_TARGET |
| 4133 : RelocInfo::CODE_TARGET_CONTEXT; | 4112 : RelocInfo::CODE_TARGET_CONTEXT; |
| 4134 frame->CallCodeObject(ic, rmode, &name_reg, 0); | 4113 frame->CallCodeObject(ic, rmode, &name_reg, 0); |
| 4135 frame->EmitPush(r0); | 4114 frame->EmitPush(r0); |
| 4136 break; | 4115 break; |
| 4137 } | 4116 } |
| 4138 | 4117 |
| 4139 case KEYED: { | 4118 case KEYED: { |
| 4140 // TODO(1241834): Make sure that this it is safe to ignore the | |
| 4141 // distinction between expressions in a typeof and not in a typeof. | |
| 4142 | |
| 4143 // TODO(181): Implement inlined version of array indexing once | 4119 // TODO(181): Implement inlined version of array indexing once |
| 4144 // loop nesting is properly tracked on ARM. | 4120 // loop nesting is properly tracked on ARM. |
| 4145 VirtualFrame* frame = cgen_->frame(); | 4121 VirtualFrame* frame = cgen_->frame(); |
| 4146 Comment cmnt(masm, "[ Load from keyed Property"); | 4122 Comment cmnt(masm, "[ Load from keyed Property"); |
| 4147 ASSERT(property != NULL); | 4123 ASSERT(property != NULL); |
| 4148 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 4124 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 4149 Variable* var = expression_->AsVariableProxy()->AsVariable(); | 4125 Variable* var = expression_->AsVariableProxy()->AsVariable(); |
| 4150 ASSERT(var == NULL || var->is_global()); | 4126 ASSERT(var == NULL || var->is_global()); |
| 4151 RelocInfo::Mode rmode = (var == NULL) | 4127 RelocInfo::Mode rmode = (var == NULL) |
| 4152 ? RelocInfo::CODE_TARGET | 4128 ? RelocInfo::CODE_TARGET |
| (...skipping 2090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6243 int CompareStub::MinorKey() { | 6219 int CompareStub::MinorKey() { |
| 6244 // Encode the two parameters in a unique 16 bit value. | 6220 // Encode the two parameters in a unique 16 bit value. |
| 6245 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); | 6221 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); |
| 6246 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); | 6222 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); |
| 6247 } | 6223 } |
| 6248 | 6224 |
| 6249 | 6225 |
| 6250 #undef __ | 6226 #undef __ |
| 6251 | 6227 |
| 6252 } } // namespace v8::internal | 6228 } } // namespace v8::internal |
| OLD | NEW |