| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 offset += JavaScriptFrameConstants::kLocal0Offset; | 68 offset += JavaScriptFrameConstants::kLocal0Offset; |
| 69 break; | 69 break; |
| 70 case Slot::CONTEXT: | 70 case Slot::CONTEXT: |
| 71 case Slot::LOOKUP: | 71 case Slot::LOOKUP: |
| 72 UNREACHABLE(); | 72 UNREACHABLE(); |
| 73 } | 73 } |
| 74 return offset; | 74 return offset; |
| 75 } | 75 } |
| 76 | 76 |
| 77 | 77 |
| 78 void FastCodeGenerator::Apply(Expression::Context context, Register reg) { | |
| 79 switch (context) { | |
| 80 case Expression::kUninitialized: | |
| 81 UNREACHABLE(); | |
| 82 case Expression::kEffect: | |
| 83 break; | |
| 84 case Expression::kValue: | |
| 85 __ push(reg); | |
| 86 break; | |
| 87 case Expression::kTest: | |
| 88 TestAndBranch(reg, true_label_, false_label_); | |
| 89 break; | |
| 90 case Expression::kValueTest: { | |
| 91 Label discard; | |
| 92 __ push(reg); | |
| 93 TestAndBranch(reg, true_label_, &discard); | |
| 94 __ bind(&discard); | |
| 95 __ Drop(1); | |
| 96 __ jmp(false_label_); | |
| 97 break; | |
| 98 } | |
| 99 case Expression::kTestValue: { | |
| 100 Label discard; | |
| 101 __ push(reg); | |
| 102 TestAndBranch(reg, &discard, false_label_); | |
| 103 __ bind(&discard); | |
| 104 __ Drop(1); | |
| 105 __ jmp(true_label_); | |
| 106 } | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 | |
| 111 void FastCodeGenerator::VisitDeclarations( | 78 void FastCodeGenerator::VisitDeclarations( |
| 112 ZoneList<Declaration*>* declarations) { | 79 ZoneList<Declaration*>* declarations) { |
| 113 int length = declarations->length(); | 80 int length = declarations->length(); |
| 114 int globals = 0; | 81 int globals = 0; |
| 115 for (int i = 0; i < length; i++) { | 82 for (int i = 0; i < length; i++) { |
| 116 Declaration* decl = declarations->at(i); | 83 Declaration* decl = declarations->at(i); |
| 117 Variable* var = decl->proxy()->var(); | 84 Variable* var = decl->proxy()->var(); |
| 118 Slot* slot = var->slot(); | 85 Slot* slot = var->slot(); |
| 119 | 86 |
| 120 // If it was not possible to allocate the variable at compile | 87 // If it was not possible to allocate the variable at compile |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 | 305 |
| 339 Breakable* target = current->AsBreakable(); | 306 Breakable* target = current->AsBreakable(); |
| 340 __ jmp(target->break_target()); | 307 __ jmp(target->break_target()); |
| 341 } | 308 } |
| 342 | 309 |
| 343 | 310 |
| 344 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 311 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
| 345 Comment cmnt(masm_, "[ ReturnStatement"); | 312 Comment cmnt(masm_, "[ ReturnStatement"); |
| 346 SetStatementPosition(stmt); | 313 SetStatementPosition(stmt); |
| 347 Expression* expr = stmt->expression(); | 314 Expression* expr = stmt->expression(); |
| 348 // Complete the statement based on the type of the subexpression. | 315 VisitForValue(expr, kAccumulator); |
| 349 if (expr->AsLiteral() != NULL) { | |
| 350 __ Move(result_register(), expr->AsLiteral()->handle()); | |
| 351 } else { | |
| 352 ASSERT_EQ(Expression::kValue, expr->context()); | |
| 353 Visit(expr); | |
| 354 __ pop(result_register()); | |
| 355 } | |
| 356 | 316 |
| 357 // Exit all nested statements. | 317 // Exit all nested statements. |
| 358 NestedStatement* current = nesting_stack_; | 318 NestedStatement* current = nesting_stack_; |
| 359 int stack_depth = 0; | 319 int stack_depth = 0; |
| 360 while (current != NULL) { | 320 while (current != NULL) { |
| 361 stack_depth = current->Exit(stack_depth); | 321 stack_depth = current->Exit(stack_depth); |
| 362 current = current->outer(); | 322 current = current->outer(); |
| 363 } | 323 } |
| 364 __ Drop(stack_depth); | 324 __ Drop(stack_depth); |
| 365 | 325 |
| 366 EmitReturnSequence(stmt->statement_pos()); | 326 EmitReturnSequence(stmt->statement_pos()); |
| 367 } | 327 } |
| 368 | 328 |
| 369 | 329 |
| 370 void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { | 330 void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { |
| 371 Comment cmnt(masm_, "[ WithEnterStatement"); | 331 Comment cmnt(masm_, "[ WithEnterStatement"); |
| 372 SetStatementPosition(stmt); | 332 SetStatementPosition(stmt); |
| 373 | 333 |
| 374 Visit(stmt->expression()); | 334 VisitForValue(stmt->expression(), kStack); |
| 375 if (stmt->is_catch_block()) { | 335 if (stmt->is_catch_block()) { |
| 376 __ CallRuntime(Runtime::kPushCatchContext, 1); | 336 __ CallRuntime(Runtime::kPushCatchContext, 1); |
| 377 } else { | 337 } else { |
| 378 __ CallRuntime(Runtime::kPushContext, 1); | 338 __ CallRuntime(Runtime::kPushContext, 1); |
| 379 } | 339 } |
| 380 // Both runtime calls return the new context in both the context and the | 340 // Both runtime calls return the new context in both the context and the |
| 381 // result registers. | 341 // result registers. |
| 382 | 342 |
| 383 // Update local stack frame context field. | 343 // Update local stack frame context field. |
| 384 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); | 344 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 ? NAMED_PROPERTY | 611 ? NAMED_PROPERTY |
| 652 : KEYED_PROPERTY; | 612 : KEYED_PROPERTY; |
| 653 } | 613 } |
| 654 | 614 |
| 655 // Evaluate LHS expression. | 615 // Evaluate LHS expression. |
| 656 switch (assign_type) { | 616 switch (assign_type) { |
| 657 case VARIABLE: | 617 case VARIABLE: |
| 658 // Nothing to do here. | 618 // Nothing to do here. |
| 659 break; | 619 break; |
| 660 case NAMED_PROPERTY: | 620 case NAMED_PROPERTY: |
| 661 Visit(prop->obj()); | 621 VisitForValue(prop->obj(), kStack); |
| 662 ASSERT_EQ(Expression::kValue, prop->obj()->context()); | |
| 663 break; | 622 break; |
| 664 case KEYED_PROPERTY: | 623 case KEYED_PROPERTY: |
| 665 Visit(prop->obj()); | 624 VisitForValue(prop->obj(), kStack); |
| 666 ASSERT_EQ(Expression::kValue, prop->obj()->context()); | 625 VisitForValue(prop->key(), kStack); |
| 667 Visit(prop->key()); | |
| 668 ASSERT_EQ(Expression::kValue, prop->key()->context()); | |
| 669 break; | 626 break; |
| 670 } | 627 } |
| 671 | 628 |
| 672 // If we have a compound assignment: Get value of LHS expression and | 629 // If we have a compound assignment: Get value of LHS expression and |
| 673 // store in on top of the stack. | 630 // store in on top of the stack. |
| 674 // Note: Relies on kValue context being 'stack'. | |
| 675 if (expr->is_compound()) { | 631 if (expr->is_compound()) { |
| 632 Location saved_location = location_; |
| 633 location_ = kStack; |
| 676 switch (assign_type) { | 634 switch (assign_type) { |
| 677 case VARIABLE: | 635 case VARIABLE: |
| 678 EmitVariableLoad(expr->target()->AsVariableProxy()->var(), | 636 EmitVariableLoad(expr->target()->AsVariableProxy()->var(), |
| 679 Expression::kValue); | 637 Expression::kValue); |
| 680 break; | 638 break; |
| 681 case NAMED_PROPERTY: | 639 case NAMED_PROPERTY: |
| 682 EmitNamedPropertyLoad(prop); | 640 EmitNamedPropertyLoad(prop); |
| 683 __ push(result_register()); | 641 __ push(result_register()); |
| 684 break; | 642 break; |
| 685 case KEYED_PROPERTY: | 643 case KEYED_PROPERTY: |
| 686 EmitKeyedPropertyLoad(prop); | 644 EmitKeyedPropertyLoad(prop); |
| 687 __ push(result_register()); | 645 __ push(result_register()); |
| 688 break; | 646 break; |
| 689 } | 647 } |
| 648 location_ = saved_location; |
| 690 } | 649 } |
| 691 | 650 |
| 692 // Evaluate RHS expression. | 651 // Evaluate RHS expression. |
| 693 Expression* rhs = expr->value(); | 652 Expression* rhs = expr->value(); |
| 694 ASSERT_EQ(Expression::kValue, rhs->context()); | 653 VisitForValue(rhs, kAccumulator); |
| 695 Visit(rhs); | |
| 696 | 654 |
| 697 // If we have a compount assignment: Apply operator. | 655 // If we have a compount assignment: Apply operator. |
| 698 if (expr->is_compound()) { | 656 if (expr->is_compound()) { |
| 699 EmitCompoundAssignmentOp(expr->binary_op(), Expression::kValue); | 657 Location saved_location = location_; |
| 658 location_ = kAccumulator; |
| 659 EmitBinaryOp(expr->binary_op(), Expression::kValue); |
| 660 location_ = saved_location; |
| 700 } | 661 } |
| 701 | 662 |
| 702 // Record source position before possible IC call. | 663 // Record source position before possible IC call. |
| 703 SetSourcePosition(expr->position()); | 664 SetSourcePosition(expr->position()); |
| 704 | 665 |
| 705 // Store the value. | 666 // Store the value. |
| 706 switch (assign_type) { | 667 switch (assign_type) { |
| 707 case VARIABLE: | 668 case VARIABLE: |
| 708 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 669 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
| 709 expr->context()); | 670 expr->context()); |
| 710 break; | 671 break; |
| 711 case NAMED_PROPERTY: | 672 case NAMED_PROPERTY: |
| 712 EmitNamedPropertyAssignment(expr); | 673 EmitNamedPropertyAssignment(expr); |
| 713 break; | 674 break; |
| 714 case KEYED_PROPERTY: | 675 case KEYED_PROPERTY: |
| 715 EmitKeyedPropertyAssignment(expr); | 676 EmitKeyedPropertyAssignment(expr); |
| 716 break; | 677 break; |
| 717 } | 678 } |
| 718 } | 679 } |
| 719 | 680 |
| 720 | 681 |
| 721 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { | 682 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { |
| 722 // Call runtime routine to allocate the catch extension object and | 683 // Call runtime routine to allocate the catch extension object and |
| 723 // assign the exception value to the catch variable. | 684 // assign the exception value to the catch variable. |
| 724 Comment cmnt(masm_, "[ CatchExtensionObject"); | 685 Comment cmnt(masm_, "[ CatchExtensionObject"); |
| 725 | 686 |
| 726 // Push key string. | 687 VisitForValue(expr->key(), kStack); |
| 727 ASSERT_EQ(Expression::kValue, expr->key()->context()); | 688 VisitForValue(expr->value(), kStack); |
| 728 Visit(expr->key()); | |
| 729 ASSERT_EQ(Expression::kValue, expr->value()->context()); | |
| 730 Visit(expr->value()); | |
| 731 | 689 |
| 732 // Create catch extension object. | 690 // Create catch extension object. |
| 733 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); | 691 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); |
| 734 | 692 |
| 735 __ push(result_register()); | 693 __ push(result_register()); |
| 736 } | 694 } |
| 737 | 695 |
| 738 | 696 |
| 739 void FastCodeGenerator::VisitThrow(Throw* expr) { | 697 void FastCodeGenerator::VisitThrow(Throw* expr) { |
| 740 Comment cmnt(masm_, "[ Throw"); | 698 Comment cmnt(masm_, "[ Throw"); |
| 741 Visit(expr->exception()); | 699 VisitForValue(expr->exception(), kStack); |
| 742 // Exception is on stack. | |
| 743 __ CallRuntime(Runtime::kThrow, 1); | 700 __ CallRuntime(Runtime::kThrow, 1); |
| 744 // Never returns here. | 701 // Never returns here. |
| 745 } | 702 } |
| 746 | 703 |
| 747 | 704 |
| 748 int FastCodeGenerator::TryFinally::Exit(int stack_depth) { | 705 int FastCodeGenerator::TryFinally::Exit(int stack_depth) { |
| 749 // The macros used here must preserve the result register. | 706 // The macros used here must preserve the result register. |
| 750 __ Drop(stack_depth); | 707 __ Drop(stack_depth); |
| 751 __ PopTryHandler(); | 708 __ PopTryHandler(); |
| 752 __ Call(finally_entry_); | 709 __ Call(finally_entry_); |
| 753 return 0; | 710 return 0; |
| 754 } | 711 } |
| 755 | 712 |
| 756 | 713 |
| 757 int FastCodeGenerator::TryCatch::Exit(int stack_depth) { | 714 int FastCodeGenerator::TryCatch::Exit(int stack_depth) { |
| 758 // The macros used here must preserve the result register. | 715 // The macros used here must preserve the result register. |
| 759 __ Drop(stack_depth); | 716 __ Drop(stack_depth); |
| 760 __ PopTryHandler(); | 717 __ PopTryHandler(); |
| 761 return 0; | 718 return 0; |
| 762 } | 719 } |
| 763 | 720 |
| 764 | 721 |
| 765 #undef __ | 722 #undef __ |
| 766 | 723 |
| 767 | 724 |
| 768 } } // namespace v8::internal | 725 } } // namespace v8::internal |
| OLD | NEW |