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