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 |