| 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 // patch with the code required by the debugger. | 103 // patch with the code required by the debugger. |
| 104 __ mov(esp, ebp); | 104 __ mov(esp, ebp); |
| 105 __ pop(ebp); | 105 __ pop(ebp); |
| 106 __ ret((fun->scope()->num_parameters() + 1) * kPointerSize); | 106 __ ret((fun->scope()->num_parameters() + 1) * kPointerSize); |
| 107 } | 107 } |
| 108 } | 108 } |
| 109 | 109 |
| 110 | 110 |
| 111 void FastCodeGenerator::Move(Location destination, Slot* source) { | 111 void FastCodeGenerator::Move(Location destination, Slot* source) { |
| 112 switch (destination.type()) { | 112 switch (destination.type()) { |
| 113 case Location::UNINITIALIZED: | 113 case Location::kUninitialized: |
| 114 UNREACHABLE(); | 114 UNREACHABLE(); |
| 115 case Location::EFFECT: | 115 case Location::kEffect: |
| 116 break; | 116 break; |
| 117 case Location::VALUE: | 117 case Location::kValue: |
| 118 __ push(Operand(ebp, SlotOffset(source))); | 118 __ push(Operand(ebp, SlotOffset(source))); |
| 119 break; | 119 break; |
| 120 } | 120 } |
| 121 } | 121 } |
| 122 | 122 |
| 123 | 123 |
| 124 void FastCodeGenerator::Move(Location destination, Literal* expr) { | 124 void FastCodeGenerator::Move(Location destination, Literal* expr) { |
| 125 switch (destination.type()) { | 125 switch (destination.type()) { |
| 126 case Location::UNINITIALIZED: | 126 case Location::kUninitialized: |
| 127 UNREACHABLE(); | 127 UNREACHABLE(); |
| 128 case Location::EFFECT: | 128 case Location::kEffect: |
| 129 break; | 129 break; |
| 130 case Location::VALUE: | 130 case Location::kValue: |
| 131 __ push(Immediate(expr->handle())); | 131 __ push(Immediate(expr->handle())); |
| 132 break; | 132 break; |
| 133 } | 133 } |
| 134 } | 134 } |
| 135 | 135 |
| 136 | 136 |
| 137 void FastCodeGenerator::Move(Slot* destination, Location source) { | 137 void FastCodeGenerator::Move(Slot* destination, Location source) { |
| 138 switch (source.type()) { | 138 switch (source.type()) { |
| 139 case Location::UNINITIALIZED: // Fall through. | 139 case Location::kUninitialized: // Fall through. |
| 140 case Location::EFFECT: | 140 case Location::kEffect: |
| 141 UNREACHABLE(); | 141 UNREACHABLE(); |
| 142 case Location::VALUE: | 142 case Location::kValue: |
| 143 __ pop(Operand(ebp, SlotOffset(destination))); | 143 __ pop(Operand(ebp, SlotOffset(destination))); |
| 144 break; | 144 break; |
| 145 } | 145 } |
| 146 } | 146 } |
| 147 | 147 |
| 148 | 148 |
| 149 void FastCodeGenerator::DropAndMove(Location destination, Register source) { | 149 void FastCodeGenerator::DropAndMove(Location destination, Register source) { |
| 150 switch (destination.type()) { | 150 switch (destination.type()) { |
| 151 case Location::UNINITIALIZED: | 151 case Location::kUninitialized: |
| 152 UNREACHABLE(); | 152 UNREACHABLE(); |
| 153 case Location::EFFECT: | 153 case Location::kEffect: |
| 154 __ add(Operand(esp), Immediate(kPointerSize)); | 154 __ add(Operand(esp), Immediate(kPointerSize)); |
| 155 break; | 155 break; |
| 156 case Location::VALUE: | 156 case Location::kValue: |
| 157 __ mov(Operand(esp, 0), source); | 157 __ mov(Operand(esp, 0), source); |
| 158 break; | 158 break; |
| 159 } | 159 } |
| 160 } | 160 } |
| 161 | 161 |
| 162 | 162 |
| 163 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 163 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 164 // Call the runtime to declare the globals. | 164 // Call the runtime to declare the globals. |
| 165 __ push(esi); // The context is the first argument. | 165 __ push(esi); // The context is the first argument. |
| 166 __ push(Immediate(pairs)); | 166 __ push(Immediate(pairs)); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 Smi::FromInt(0))); | 345 Smi::FromInt(0))); |
| 346 Visit(value); | 346 Visit(value); |
| 347 ASSERT(value->location().is_value()); | 347 ASSERT(value->location().is_value()); |
| 348 __ CallRuntime(Runtime::kDefineAccessor, 4); | 348 __ CallRuntime(Runtime::kDefineAccessor, 4); |
| 349 __ mov(eax, Operand(esp, 0)); // Restore result into eax. | 349 __ mov(eax, Operand(esp, 0)); // Restore result into eax. |
| 350 break; | 350 break; |
| 351 default: UNREACHABLE(); | 351 default: UNREACHABLE(); |
| 352 } | 352 } |
| 353 } | 353 } |
| 354 switch (expr->location().type()) { | 354 switch (expr->location().type()) { |
| 355 case Location::UNINITIALIZED: | 355 case Location::kUninitialized: |
| 356 UNREACHABLE(); | 356 UNREACHABLE(); |
| 357 case Location::EFFECT: | 357 case Location::kEffect: |
| 358 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); | 358 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); |
| 359 break; | 359 break; |
| 360 case Location::VALUE: | 360 case Location::kValue: |
| 361 if (!result_saved) __ push(eax); | 361 if (!result_saved) __ push(eax); |
| 362 break; | 362 break; |
| 363 } | 363 } |
| 364 } | 364 } |
| 365 | 365 |
| 366 | 366 |
| 367 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 367 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 368 Comment cmnt(masm_, "[ ArrayLiteral"); | 368 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 369 Label make_clone; | 369 Label make_clone; |
| 370 | 370 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 __ mov(ebx, Operand(esp, 0)); // Copy of array literal. | 419 __ mov(ebx, Operand(esp, 0)); // Copy of array literal. |
| 420 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); | 420 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); |
| 421 int offset = FixedArray::kHeaderSize + (i * kPointerSize); | 421 int offset = FixedArray::kHeaderSize + (i * kPointerSize); |
| 422 __ mov(FieldOperand(ebx, offset), eax); | 422 __ mov(FieldOperand(ebx, offset), eax); |
| 423 | 423 |
| 424 // Update the write barrier for the array store. | 424 // Update the write barrier for the array store. |
| 425 __ RecordWrite(ebx, offset, eax, ecx); | 425 __ RecordWrite(ebx, offset, eax, ecx); |
| 426 } | 426 } |
| 427 | 427 |
| 428 switch (expr->location().type()) { | 428 switch (expr->location().type()) { |
| 429 case Location::UNINITIALIZED: | 429 case Location::kUninitialized: |
| 430 UNREACHABLE(); | 430 UNREACHABLE(); |
| 431 case Location::EFFECT: | 431 case Location::kEffect: |
| 432 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); | 432 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); |
| 433 break; | 433 break; |
| 434 case Location::VALUE: | 434 case Location::kValue: |
| 435 if (!result_saved) __ push(eax); | 435 if (!result_saved) __ push(eax); |
| 436 break; | 436 break; |
| 437 } | 437 } |
| 438 } | 438 } |
| 439 | 439 |
| 440 | 440 |
| 441 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 441 void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
| 442 Comment cmnt(masm_, "[ Assignment"); | 442 Comment cmnt(masm_, "[ Assignment"); |
| 443 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); | 443 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); |
| 444 | 444 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 474 if (rhs->AsLiteral() != NULL) { | 474 if (rhs->AsLiteral() != NULL) { |
| 475 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 475 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a |
| 476 // discarded result. Always perform the assignment. | 476 // discarded result. Always perform the assignment. |
| 477 __ mov(eax, rhs->AsLiteral()->handle()); | 477 __ mov(eax, rhs->AsLiteral()->handle()); |
| 478 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 478 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
| 479 Move(expr->location(), eax); | 479 Move(expr->location(), eax); |
| 480 } else { | 480 } else { |
| 481 ASSERT(rhs->location().is_value()); | 481 ASSERT(rhs->location().is_value()); |
| 482 Visit(rhs); | 482 Visit(rhs); |
| 483 switch (expr->location().type()) { | 483 switch (expr->location().type()) { |
| 484 case Location::UNINITIALIZED: | 484 case Location::kUninitialized: |
| 485 UNREACHABLE(); | 485 UNREACHABLE(); |
| 486 case Location::EFFECT: | 486 case Location::kEffect: |
| 487 // Case 'var = temp'. Discard right-hand-side temporary. | 487 // Case 'var = temp'. Discard right-hand-side temporary. |
| 488 Move(var->slot(), rhs->location()); | 488 Move(var->slot(), rhs->location()); |
| 489 break; | 489 break; |
| 490 case Location::VALUE: | 490 case Location::kValue: |
| 491 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side | 491 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side |
| 492 // temporary on the stack. | 492 // temporary on the stack. |
| 493 __ mov(eax, Operand(esp, 0)); | 493 __ mov(eax, Operand(esp, 0)); |
| 494 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 494 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
| 495 break; | 495 break; |
| 496 } | 496 } |
| 497 } | 497 } |
| 498 } | 498 } |
| 499 } | 499 } |
| 500 | 500 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 525 Visit(expr->key()); | 525 Visit(expr->key()); |
| 526 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 526 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 527 __ call(ic, RelocInfo::CODE_TARGET); | 527 __ call(ic, RelocInfo::CODE_TARGET); |
| 528 // By emitting a nop we make sure that we do not have a "test eax,..." | 528 // By emitting a nop we make sure that we do not have a "test eax,..." |
| 529 // instruction after the call it is treated specially by the LoadIC code. | 529 // instruction after the call it is treated specially by the LoadIC code. |
| 530 __ nop(); | 530 __ nop(); |
| 531 // Drop key left on the stack by IC. | 531 // Drop key left on the stack by IC. |
| 532 __ add(Operand(esp), Immediate(kPointerSize)); | 532 __ add(Operand(esp), Immediate(kPointerSize)); |
| 533 } | 533 } |
| 534 switch (expr->location().type()) { | 534 switch (expr->location().type()) { |
| 535 case Location::UNINITIALIZED: | 535 case Location::kUninitialized: |
| 536 UNREACHABLE(); | 536 UNREACHABLE(); |
| 537 case Location::VALUE: | 537 case Location::kValue: |
| 538 __ mov(Operand(esp, 0), eax); | 538 __ mov(Operand(esp, 0), eax); |
| 539 break; | 539 break; |
| 540 case Location::EFFECT: | 540 case Location::kEffect: |
| 541 __ add(Operand(esp), Immediate(kPointerSize)); | 541 __ add(Operand(esp), Immediate(kPointerSize)); |
| 542 break; | 542 break; |
| 543 } | 543 } |
| 544 } | 544 } |
| 545 | 545 |
| 546 | 546 |
| 547 void FastCodeGenerator::VisitCall(Call* expr) { | 547 void FastCodeGenerator::VisitCall(Call* expr) { |
| 548 Expression* fun = expr->expression(); | 548 Expression* fun = expr->expression(); |
| 549 ZoneList<Expression*>* args = expr->arguments(); | 549 ZoneList<Expression*>* args = expr->arguments(); |
| 550 Variable* var = fun->AsVariableProxy()->AsVariable(); | 550 Variable* var = fun->AsVariableProxy()->AsVariable(); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 | 648 |
| 649 // Compile the left-hand value into eax. Put it on the stack if we may | 649 // Compile the left-hand value into eax. Put it on the stack if we may |
| 650 // need it as the value of the whole expression. | 650 // need it as the value of the whole expression. |
| 651 if (left->AsLiteral() != NULL) { | 651 if (left->AsLiteral() != NULL) { |
| 652 __ mov(eax, left->AsLiteral()->handle()); | 652 __ mov(eax, left->AsLiteral()->handle()); |
| 653 if (destination.is_value()) __ push(eax); | 653 if (destination.is_value()) __ push(eax); |
| 654 } else { | 654 } else { |
| 655 Visit(left); | 655 Visit(left); |
| 656 ASSERT(left->location().is_value()); | 656 ASSERT(left->location().is_value()); |
| 657 switch (destination.type()) { | 657 switch (destination.type()) { |
| 658 case Location::UNINITIALIZED: | 658 case Location::kUninitialized: |
| 659 UNREACHABLE(); | 659 UNREACHABLE(); |
| 660 case Location::EFFECT: | 660 case Location::kEffect: |
| 661 // Pop the left-hand value into eax because we will not need it as the | 661 // Pop the left-hand value into eax because we will not need it as the |
| 662 // final result. | 662 // final result. |
| 663 __ pop(eax); | 663 __ pop(eax); |
| 664 break; | 664 break; |
| 665 case Location::VALUE: | 665 case Location::kValue: |
| 666 // Copy the left-hand value into eax because we may need it as the | 666 // Copy the left-hand value into eax because we may need it as the |
| 667 // final result. | 667 // final result. |
| 668 __ mov(eax, Operand(esp, 0)); | 668 __ mov(eax, Operand(esp, 0)); |
| 669 break; | 669 break; |
| 670 } | 670 } |
| 671 } | 671 } |
| 672 // The left-hand value is in eax. It is also on the stack iff the | 672 // The left-hand value is in eax. It is also on the stack iff the |
| 673 // destination location is temporary. | 673 // destination location is temporary. |
| 674 | 674 |
| 675 // Perform fast checks assumed by the stub. | 675 // Perform fast checks assumed by the stub. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 691 __ CallStub(&stub); | 691 __ CallStub(&stub); |
| 692 __ test(eax, Operand(eax)); // The stub returns nonzero for true. | 692 __ test(eax, Operand(eax)); // The stub returns nonzero for true. |
| 693 __ j(not_zero, &done); | 693 __ j(not_zero, &done); |
| 694 | 694 |
| 695 __ bind(&eval_right); | 695 __ bind(&eval_right); |
| 696 // Discard the left-hand value if present on the stack. | 696 // Discard the left-hand value if present on the stack. |
| 697 if (destination.is_value()) { | 697 if (destination.is_value()) { |
| 698 __ add(Operand(esp), Immediate(kPointerSize)); | 698 __ add(Operand(esp), Immediate(kPointerSize)); |
| 699 } | 699 } |
| 700 // Save or discard the right-hand value as needed. | 700 // Save or discard the right-hand value as needed. |
| 701 if (right->AsLiteral() != NULL) { | 701 Visit(right); |
| 702 Move(destination, right->AsLiteral()); | 702 ASSERT_EQ(destination.type(), right->location().type()); |
| 703 } else { | |
| 704 Visit(right); | |
| 705 Move(destination, right->location()); | |
| 706 } | |
| 707 | 703 |
| 708 __ bind(&done); | 704 __ bind(&done); |
| 709 } | 705 } |
| 710 | 706 |
| 711 | 707 |
| 712 } } // namespace v8::internal | 708 } } // namespace v8::internal |
| OLD | NEW |