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 |