| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 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 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 if (!result_saved) __ push(rax); | 447 if (!result_saved) __ push(rax); |
| 448 break; | 448 break; |
| 449 } | 449 } |
| 450 } | 450 } |
| 451 | 451 |
| 452 | 452 |
| 453 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 453 void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
| 454 Comment cmnt(masm_, "[ Assignment"); | 454 Comment cmnt(masm_, "[ Assignment"); |
| 455 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); | 455 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); |
| 456 | 456 |
| 457 // Left-hand side can only be a global or a (parameter or local) slot. | 457 // Record the source position for the assignment. |
| 458 SetSourcePosition(expr->position()); |
| 459 |
| 460 // Left-hand side can only be a property, a global or |
| 461 // a (parameter or local) slot. |
| 458 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 462 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| 459 ASSERT(var != NULL); | |
| 460 ASSERT(var->is_global() || var->slot() != NULL); | |
| 461 | |
| 462 Expression* rhs = expr->value(); | 463 Expression* rhs = expr->value(); |
| 463 Location destination = expr->location(); | 464 if (var == NULL) { |
| 464 if (var->is_global()) { | 465 // Assignment to a property. |
| 466 ASSERT(expr->target()->AsProperty() != NULL); |
| 467 Property* prop = expr->target()->AsProperty(); |
| 468 Visit(prop->obj()); |
| 469 Literal* literal_key = prop->key()->AsLiteral(); |
| 470 uint32_t dummy; |
| 471 if (literal_key != NULL && |
| 472 literal_key->handle()->IsSymbol() && |
| 473 !String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) { |
| 474 // NAMED property assignment |
| 475 Visit(rhs); |
| 476 Move(rax, rhs->location()); |
| 477 __ Move(rcx, literal_key->handle()); |
| 478 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 479 __ call(ic, RelocInfo::CODE_TARGET); |
| 480 __ nop(); |
| 481 } else { |
| 482 // KEYED property assignment |
| 483 Visit(prop->key()); |
| 484 Visit(rhs); |
| 485 Move(rax, rhs->location()); |
| 486 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 487 __ call(ic, RelocInfo::CODE_TARGET); |
| 488 __ nop(); |
| 489 // Drop key from the stack |
| 490 __ addq(rsp, Immediate(kPointerSize)); |
| 491 } |
| 492 // Overwrite the receiver on the stack with the result if needed. |
| 493 DropAndMove(expr->location(), rax); |
| 494 } else if (var->is_global()) { |
| 465 // Assignment to a global variable, use inline caching. Right-hand-side | 495 // Assignment to a global variable, use inline caching. Right-hand-side |
| 466 // value is passed in rax, variable name in rcx, and the global object | 496 // value is passed in rax, variable name in rcx, and the global object |
| 467 // on the stack. | 497 // on the stack. |
| 468 | 498 |
| 469 // Code for the right-hand-side expression depends on its type. | 499 // Code for the right-hand-side expression depends on its type. |
| 470 if (rhs->AsLiteral() != NULL) { | 500 if (rhs->AsLiteral() != NULL) { |
| 471 __ Move(rax, rhs->AsLiteral()->handle()); | 501 __ Move(rax, rhs->AsLiteral()->handle()); |
| 472 } else { | 502 } else { |
| 473 ASSERT(rhs->location().is_value()); | 503 ASSERT(rhs->location().is_value()); |
| 474 Visit(rhs); | 504 Visit(rhs); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 // Evaluate receiver. | 553 // Evaluate receiver. |
| 524 Visit(expr->obj()); | 554 Visit(expr->obj()); |
| 525 | 555 |
| 526 if (key->AsLiteral() != NULL && key->AsLiteral()->handle()->IsSymbol() && | 556 if (key->AsLiteral() != NULL && key->AsLiteral()->handle()->IsSymbol() && |
| 527 !String::cast(*(key->AsLiteral()->handle()))->AsArrayIndex(&dummy)) { | 557 !String::cast(*(key->AsLiteral()->handle()))->AsArrayIndex(&dummy)) { |
| 528 // Do a NAMED property load. | 558 // Do a NAMED property load. |
| 529 // The IC expects the property name in rcx and the receiver on the stack. | 559 // The IC expects the property name in rcx and the receiver on the stack. |
| 530 __ Move(rcx, key->AsLiteral()->handle()); | 560 __ Move(rcx, key->AsLiteral()->handle()); |
| 531 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 561 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 532 __ call(ic, RelocInfo::CODE_TARGET); | 562 __ call(ic, RelocInfo::CODE_TARGET); |
| 533 // By emitting a nop we make sure that we do not have a "test eax,..." | 563 // By emitting a nop we make sure that we do not have a "test rax,..." |
| 534 // instruction after the call it is treated specially by the LoadIC code. | 564 // instruction after the call it is treated specially by the LoadIC code. |
| 535 __ nop(); | 565 __ nop(); |
| 536 } else { | 566 } else { |
| 537 // Do a KEYED property load. | 567 // Do a KEYED property load. |
| 538 Visit(expr->key()); | 568 Visit(expr->key()); |
| 539 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 569 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 540 __ call(ic, RelocInfo::CODE_TARGET); | 570 __ call(ic, RelocInfo::CODE_TARGET); |
| 541 // By emitting a nop we make sure that we do not have a "test ..." | 571 // By emitting a nop we make sure that we do not have a "test rax,..." |
| 542 // instruction after the call it is treated specially by the LoadIC code. | 572 // instruction after the call it is treated specially by the LoadIC code. |
| 543 __ nop(); | 573 __ nop(); |
| 544 // Drop key left on the stack by IC. | 574 // Drop key left on the stack by IC. |
| 545 __ addq(rsp, Immediate(kPointerSize)); | 575 __ addq(rsp, Immediate(kPointerSize)); |
| 546 } | 576 } |
| 547 switch (expr->location().type()) { | 577 DropAndMove(expr->location(), rax); |
| 548 case Location::kUninitialized: | |
| 549 UNREACHABLE(); | |
| 550 case Location::kValue: | |
| 551 __ movq(Operand(rsp, 0), rax); | |
| 552 break; | |
| 553 case Location::kEffect: | |
| 554 __ addq(rsp, Immediate(kPointerSize)); | |
| 555 break; | |
| 556 } | |
| 557 } | 578 } |
| 558 | 579 |
| 559 | 580 |
| 560 void FastCodeGenerator::VisitCall(Call* expr) { | 581 void FastCodeGenerator::VisitCall(Call* expr) { |
| 561 Expression* fun = expr->expression(); | 582 Expression* fun = expr->expression(); |
| 562 ZoneList<Expression*>* args = expr->arguments(); | 583 ZoneList<Expression*>* args = expr->arguments(); |
| 563 Variable* var = fun->AsVariableProxy()->AsVariable(); | 584 Variable* var = fun->AsVariableProxy()->AsVariable(); |
| 564 ASSERT(var != NULL && !var->is_this() && var->is_global()); | 585 ASSERT(var != NULL && !var->is_this() && var->is_global()); |
| 565 ASSERT(!var->is_possibly_eval()); | 586 ASSERT(!var->is_possibly_eval()); |
| 566 | 587 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 } | 792 } |
| 772 // Save or discard the right-hand value as needed. | 793 // Save or discard the right-hand value as needed. |
| 773 Visit(right); | 794 Visit(right); |
| 774 ASSERT_EQ(destination.type(), right->location().type()); | 795 ASSERT_EQ(destination.type(), right->location().type()); |
| 775 | 796 |
| 776 __ bind(&done); | 797 __ bind(&done); |
| 777 } | 798 } |
| 778 | 799 |
| 779 | 800 |
| 780 } } // namespace v8::internal | 801 } } // namespace v8::internal |
| OLD | NEW |