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 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 if (!result_saved) __ push(r0); | 448 if (!result_saved) __ push(r0); |
449 break; | 449 break; |
450 } | 450 } |
451 } | 451 } |
452 | 452 |
453 | 453 |
454 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 454 void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
455 Comment cmnt(masm_, "[ Assignment"); | 455 Comment cmnt(masm_, "[ Assignment"); |
456 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); | 456 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); |
457 | 457 |
458 // Left-hand side can only be a global or a (parameter or local) slot. | 458 // Record the source position for the assignment. |
| 459 SetSourcePosition(expr->position()); |
| 460 |
| 461 // Left-hand side can only be a property, a global or |
| 462 // a (parameter or local) slot. |
459 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 463 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
460 ASSERT(var != NULL); | |
461 ASSERT(var->is_global() || var->slot() != NULL); | |
462 | |
463 Expression* rhs = expr->value(); | 464 Expression* rhs = expr->value(); |
464 Location destination = expr->location(); | 465 if (var == NULL) { |
465 if (var->is_global()) { | 466 // Assignment to a property. |
| 467 ASSERT(expr->target()->AsProperty() != NULL); |
| 468 Property* prop = expr->target()->AsProperty(); |
| 469 Visit(prop->obj()); |
| 470 Literal* literal_key = prop->key()->AsLiteral(); |
| 471 uint32_t dummy; |
| 472 if (literal_key != NULL && |
| 473 literal_key->handle()->IsSymbol() && |
| 474 !String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) { |
| 475 // NAMED property assignment |
| 476 Visit(rhs); |
| 477 Move(r0, rhs->location()); |
| 478 __ mov(r2, Operand(literal_key->handle())); |
| 479 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 480 __ Call(ic, RelocInfo::CODE_TARGET); |
| 481 } else { |
| 482 // KEYED property assignment |
| 483 Visit(prop->key()); |
| 484 Visit(rhs); |
| 485 Move(r0, rhs->location()); |
| 486 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 487 __ Call(ic, RelocInfo::CODE_TARGET); |
| 488 // Drop key from the stack |
| 489 __ pop(); |
| 490 } |
| 491 // Overwrite the receiver on the stack with the result if needed. |
| 492 DropAndMove(expr->location(), r0); |
| 493 } else if (var->is_global()) { |
466 // Assignment to a global variable, use inline caching. Right-hand-side | 494 // Assignment to a global variable, use inline caching. Right-hand-side |
467 // value is passed in r0, variable name in r2, and the global object on | 495 // value is passed in r0, variable name in r2, and the global object on |
468 // the stack. | 496 // the stack. |
469 | 497 |
470 // Code for the right-hand-side expression depends on its type. | 498 // Code for the right-hand-side expression depends on its type. |
471 if (rhs->AsLiteral() != NULL) { | 499 if (rhs->AsLiteral() != NULL) { |
472 __ mov(r0, Operand(rhs->AsLiteral()->handle())); | 500 __ mov(r0, Operand(rhs->AsLiteral()->handle())); |
473 } else { | 501 } else { |
474 ASSERT(rhs->location().is_value()); | 502 ASSERT(rhs->location().is_value()); |
475 Visit(rhs); | 503 Visit(rhs); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 // Evaluate receiver. | 555 // Evaluate receiver. |
528 Visit(expr->obj()); | 556 Visit(expr->obj()); |
529 | 557 |
530 if (key->AsLiteral() != NULL && key->AsLiteral()->handle()->IsSymbol() && | 558 if (key->AsLiteral() != NULL && key->AsLiteral()->handle()->IsSymbol() && |
531 !String::cast(*(key->AsLiteral()->handle()))->AsArrayIndex(&dummy)) { | 559 !String::cast(*(key->AsLiteral()->handle()))->AsArrayIndex(&dummy)) { |
532 // Do a NAMED property load. | 560 // Do a NAMED property load. |
533 // The IC expects the property name in ecx and the receiver on the stack. | 561 // The IC expects the property name in ecx and the receiver on the stack. |
534 __ mov(r2, Operand(key->AsLiteral()->handle())); | 562 __ mov(r2, Operand(key->AsLiteral()->handle())); |
535 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 563 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
536 __ Call(ic, RelocInfo::CODE_TARGET); | 564 __ Call(ic, RelocInfo::CODE_TARGET); |
537 // By emitting a nop we make sure that we do not have a "test eax,..." | |
538 // instruction after the call it is treated specially by the LoadIC code. | |
539 __ nop(); | |
540 } else { | 565 } else { |
541 // Do a KEYED property load. | 566 // Do a KEYED property load. |
542 Visit(expr->key()); | 567 Visit(expr->key()); |
543 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 568 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
544 __ Call(ic, RelocInfo::CODE_TARGET); | 569 __ Call(ic, RelocInfo::CODE_TARGET); |
545 // By emitting a nop we make sure that we do not have a "test eax,..." | |
546 // instruction after the call it is treated specially by the LoadIC code. | |
547 __ nop(); | |
548 // Drop key and receiver left on the stack by IC. | 570 // Drop key and receiver left on the stack by IC. |
549 __ pop(); | 571 __ pop(); |
550 } | 572 } |
551 switch (expr->location().type()) { | 573 DropAndMove(expr->location(), r0); |
552 case Location::kUninitialized: | |
553 UNREACHABLE(); | |
554 case Location::kValue: | |
555 __ str(r0, MemOperand(sp)); | |
556 break; | |
557 case Location::kEffect: | |
558 __ pop(); | |
559 } | |
560 } | 574 } |
561 | 575 |
562 | 576 |
563 void FastCodeGenerator::VisitCall(Call* expr) { | 577 void FastCodeGenerator::VisitCall(Call* expr) { |
564 Comment cmnt(masm_, "[ Call"); | 578 Comment cmnt(masm_, "[ Call"); |
565 Expression* fun = expr->expression(); | 579 Expression* fun = expr->expression(); |
566 ZoneList<Expression*>* args = expr->arguments(); | 580 ZoneList<Expression*>* args = expr->arguments(); |
567 Variable* var = fun->AsVariableProxy()->AsVariable(); | 581 Variable* var = fun->AsVariableProxy()->AsVariable(); |
568 ASSERT(var != NULL && !var->is_this() && var->is_global()); | 582 ASSERT(var != NULL && !var->is_this() && var->is_global()); |
569 ASSERT(!var->is_possibly_eval()); | 583 ASSERT(!var->is_possibly_eval()); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 // Discard the left-hand value if present on the stack. | 748 // Discard the left-hand value if present on the stack. |
735 if (destination.is_value()) __ pop(); | 749 if (destination.is_value()) __ pop(); |
736 // Save or discard the right-hand value as needed. | 750 // Save or discard the right-hand value as needed. |
737 Visit(right); | 751 Visit(right); |
738 ASSERT_EQ(destination.type(), right->location().type()); | 752 ASSERT_EQ(destination.type(), right->location().type()); |
739 | 753 |
740 __ bind(&done); | 754 __ bind(&done); |
741 } | 755 } |
742 | 756 |
743 } } // namespace v8::internal | 757 } } // namespace v8::internal |
OLD | NEW |