| 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 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 TestAndBranch(eax, &discard, false_label_); | 579 TestAndBranch(eax, &discard, false_label_); |
| 580 __ bind(&discard); | 580 __ bind(&discard); |
| 581 __ add(Operand(esp), Immediate(kPointerSize)); | 581 __ add(Operand(esp), Immediate(kPointerSize)); |
| 582 __ jmp(true_label_); | 582 __ jmp(true_label_); |
| 583 break; | 583 break; |
| 584 } | 584 } |
| 585 } | 585 } |
| 586 } | 586 } |
| 587 | 587 |
| 588 | 588 |
| 589 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 589 void FastCodeGenerator::EmitVariableAssignment(Expression::Context context, |
| 590 Comment cmnt(masm_, "[ Assignment"); | 590 Variable* var) { |
| 591 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); | 591 if (var->is_global()) { |
| 592 | |
| 593 // Record the source position for the assignment. | |
| 594 SetSourcePosition(expr->position()); | |
| 595 | |
| 596 // Left-hand side can only be a property, a global or | |
| 597 // a (parameter or local) slot. | |
| 598 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | |
| 599 Expression* rhs = expr->value(); | |
| 600 if (var == NULL) { | |
| 601 // Assignment to a property. | |
| 602 ASSERT(expr->target()->AsProperty() != NULL); | |
| 603 Property* prop = expr->target()->AsProperty(); | |
| 604 Visit(prop->obj()); | |
| 605 Literal* literal_key = prop->key()->AsLiteral(); | |
| 606 uint32_t dummy; | |
| 607 if (literal_key != NULL && | |
| 608 literal_key->handle()->IsSymbol() && | |
| 609 !String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) { | |
| 610 // NAMED property assignment | |
| 611 Visit(rhs); | |
| 612 ASSERT_EQ(Expression::kValue, rhs->context()); | |
| 613 __ pop(eax); | |
| 614 __ mov(ecx, Immediate(literal_key->handle())); | |
| 615 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | |
| 616 __ call(ic, RelocInfo::CODE_TARGET); | |
| 617 __ nop(); | |
| 618 } else { | |
| 619 // KEYED property assignment | |
| 620 Visit(prop->key()); | |
| 621 Visit(rhs); | |
| 622 ASSERT_EQ(Expression::kValue, rhs->context()); | |
| 623 __ pop(eax); | |
| 624 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | |
| 625 __ call(ic, RelocInfo::CODE_TARGET); | |
| 626 __ nop(); | |
| 627 // Drop key from the stack | |
| 628 __ add(Operand(esp), Immediate(kPointerSize)); | |
| 629 } | |
| 630 // Overwrite the receiver on the stack with the result if needed. | |
| 631 DropAndMove(expr->context(), eax); | |
| 632 } else if (var->is_global()) { | |
| 633 // Assignment to a global variable, use inline caching. Right-hand-side | 592 // Assignment to a global variable, use inline caching. Right-hand-side |
| 634 // value is passed in eax, variable name in ecx, and the global object | 593 // value is passed in eax, variable name in ecx, and the global object |
| 635 // on the stack. | 594 // on the stack. |
| 636 | 595 __ pop(eax); |
| 637 // Code for the right-hand-side expression depends on its type. | |
| 638 if (rhs->AsLiteral() != NULL) { | |
| 639 __ mov(eax, rhs->AsLiteral()->handle()); | |
| 640 } else { | |
| 641 ASSERT_EQ(Expression::kValue, rhs->context()); | |
| 642 Visit(rhs); | |
| 643 __ pop(eax); | |
| 644 } | |
| 645 // Record position for debugger. | |
| 646 SetSourcePosition(expr->position()); | |
| 647 __ mov(ecx, var->name()); | 596 __ mov(ecx, var->name()); |
| 648 __ push(CodeGenerator::GlobalObject()); | 597 __ push(CodeGenerator::GlobalObject()); |
| 649 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 598 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 650 __ call(ic, RelocInfo::CODE_TARGET); | 599 __ call(ic, RelocInfo::CODE_TARGET); |
| 651 // Overwrite the global object on the stack with the result if needed. | 600 // Overwrite the global object on the stack with the result if needed. |
| 652 DropAndMove(expr->context(), eax); | 601 DropAndMove(context, eax); |
| 653 } else { | 602 } else { |
| 654 // Local or parameter assignment. | 603 switch (context) { |
| 655 ASSERT(var->slot() != NULL); | 604 case Expression::kUninitialized: |
| 656 | 605 UNREACHABLE(); |
| 657 // Code for the right-hand side expression depends on its type. | 606 case Expression::kEffect: |
| 658 if (rhs->AsLiteral() != NULL) { | 607 // Perform assignment and discard value. |
| 659 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 608 __ pop(Operand(ebp, SlotOffset(var->slot()))); |
| 660 // discarded result. Always perform the assignment. | 609 break; |
| 661 __ mov(eax, rhs->AsLiteral()->handle()); | 610 case Expression::kValue: |
| 662 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 611 // Perform assignment and preserve value. |
| 663 Move(expr->context(), eax); | 612 __ mov(eax, Operand(esp, 0)); |
| 664 } else { | 613 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
| 665 ASSERT_EQ(Expression::kValue, rhs->context()); | 614 break; |
| 666 Visit(rhs); | 615 case Expression::kTest: |
| 667 switch (expr->context()) { | 616 // Perform assignment and test (and discard) value. |
| 668 case Expression::kUninitialized: | 617 __ pop(eax); |
| 669 UNREACHABLE(); | 618 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
| 670 case Expression::kEffect: | 619 TestAndBranch(eax, true_label_, false_label_); |
| 671 // Case 'var = temp'. Discard right-hand-side temporary. | 620 break; |
| 672 __ pop(Operand(ebp, SlotOffset(var->slot()))); | 621 case Expression::kValueTest: { |
| 673 break; | 622 Label discard; |
| 674 case Expression::kValue: | 623 __ mov(eax, Operand(esp, 0)); |
| 675 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side | 624 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
| 676 // temporary on the stack. | 625 TestAndBranch(eax, true_label_, &discard); |
| 677 __ mov(eax, Operand(esp, 0)); | 626 __ bind(&discard); |
| 678 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 627 __ add(Operand(esp), Immediate(kPointerSize)); |
| 679 break; | 628 __ jmp(false_label_); |
| 680 case Expression::kTest: | 629 break; |
| 681 // Case 'if (var = temp) ...'. | 630 } |
| 682 __ pop(eax); | 631 case Expression::kTestValue: { |
| 683 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 632 Label discard; |
| 684 TestAndBranch(eax, true_label_, false_label_); | 633 __ mov(eax, Operand(esp, 0)); |
| 685 break; | 634 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
| 686 case Expression::kValueTest: { | 635 TestAndBranch(eax, &discard, false_label_); |
| 687 // Case '(var = temp) || ...' in value context. | 636 __ bind(&discard); |
| 688 Label discard; | 637 __ add(Operand(esp), Immediate(kPointerSize)); |
| 689 __ mov(eax, Operand(esp, 0)); | 638 __ jmp(true_label_); |
| 690 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 639 break; |
| 691 TestAndBranch(eax, true_label_, &discard); | |
| 692 __ bind(&discard); | |
| 693 __ add(Operand(esp), Immediate(kPointerSize)); | |
| 694 __ jmp(false_label_); | |
| 695 break; | |
| 696 } | |
| 697 case Expression::kTestValue: { | |
| 698 // Case '(var = temp) && ...' in value context. | |
| 699 Label discard; | |
| 700 __ mov(eax, Operand(esp, 0)); | |
| 701 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | |
| 702 TestAndBranch(eax, &discard, false_label_); | |
| 703 __ bind(&discard); | |
| 704 __ add(Operand(esp), Immediate(kPointerSize)); | |
| 705 __ jmp(true_label_); | |
| 706 break; | |
| 707 } | |
| 708 } | 640 } |
| 709 } | 641 } |
| 710 } | 642 } |
| 711 } | 643 } |
| 712 | 644 |
| 713 | 645 |
| 646 void FastCodeGenerator::EmitNamedPropertyAssignment( |
| 647 Expression::Context context, |
| 648 Handle<Object> name) { |
| 649 __ pop(eax); |
| 650 __ mov(ecx, name); |
| 651 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 652 __ call(ic, RelocInfo::CODE_TARGET); |
| 653 DropAndMove(context, eax); |
| 654 } |
| 655 |
| 656 |
| 657 void FastCodeGenerator::EmitKeyedPropertyAssignment( |
| 658 Expression::Context context) { |
| 659 __ pop(eax); |
| 660 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 661 __ call(ic, RelocInfo::CODE_TARGET); |
| 662 // This nop signals to the IC that there is no inlined code at the call |
| 663 // site for it to patch. |
| 664 __ nop(); |
| 665 // Receiver and key are still on stack. |
| 666 __ add(Operand(esp), Immediate(2 * kPointerSize)); |
| 667 Move(context, eax); |
| 668 } |
| 669 |
| 670 |
| 714 void FastCodeGenerator::VisitProperty(Property* expr) { | 671 void FastCodeGenerator::VisitProperty(Property* expr) { |
| 715 Comment cmnt(masm_, "[ Property"); | 672 Comment cmnt(masm_, "[ Property"); |
| 716 Expression* key = expr->key(); | 673 Expression* key = expr->key(); |
| 717 uint32_t dummy; | 674 uint32_t dummy; |
| 718 | 675 |
| 719 // Record the source position for the property load. | 676 // Record the source position for the property load. |
| 720 SetSourcePosition(expr->position()); | 677 SetSourcePosition(expr->position()); |
| 721 | 678 |
| 722 // Evaluate receiver. | 679 // Evaluate receiver. |
| 723 Visit(expr->obj()); | 680 Visit(expr->obj()); |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 default: | 930 default: |
| 974 UNREACHABLE(); | 931 UNREACHABLE(); |
| 975 } | 932 } |
| 976 } | 933 } |
| 977 | 934 |
| 978 | 935 |
| 979 #undef __ | 936 #undef __ |
| 980 | 937 |
| 981 | 938 |
| 982 } } // namespace v8::internal | 939 } } // namespace v8::internal |
| OLD | NEW |