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 |