OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 3745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3756 // continue. | 3756 // continue. |
3757 if (has_valid_frame()) { | 3757 if (has_valid_frame()) { |
3758 // Record the source position of the statement as this code which | 3758 // Record the source position of the statement as this code which |
3759 // is after the code for the body actually belongs to the loop | 3759 // is after the code for the body actually belongs to the loop |
3760 // statement and not the body. | 3760 // statement and not the body. |
3761 CodeForStatementPosition(node); | 3761 CodeForStatementPosition(node); |
3762 Visit(node->next()); | 3762 Visit(node->next()); |
3763 } | 3763 } |
3764 } | 3764 } |
3765 | 3765 |
| 3766 // The update expression resets the type of the loop variable. So we |
| 3767 // set it to smi before compiling the test expression. |
| 3768 if (node->is_fast_smi_loop()) { |
| 3769 // Set number type of the loop variable to smi. |
| 3770 Slot* slot = node->loop_variable()->slot(); |
| 3771 ASSERT(slot->type() == Slot::LOCAL); |
| 3772 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); |
| 3773 if (FLAG_debug_code) { |
| 3774 frame_->PushLocalAt(slot->index()); |
| 3775 Result var = frame_->Pop(); |
| 3776 var.ToRegister(); |
| 3777 __ AbortIfNotSmi(var.reg(), "Loop variable not a smi."); |
| 3778 } |
| 3779 } |
| 3780 |
3766 // Based on the condition analysis, compile the backward jump as | 3781 // Based on the condition analysis, compile the backward jump as |
3767 // necessary. | 3782 // necessary. |
3768 switch (info) { | 3783 switch (info) { |
3769 case ALWAYS_TRUE: | 3784 case ALWAYS_TRUE: |
3770 if (has_valid_frame()) { | 3785 if (has_valid_frame()) { |
3771 if (node->next() == NULL) { | 3786 if (node->next() == NULL) { |
3772 node->continue_target()->Jump(); | 3787 node->continue_target()->Jump(); |
3773 } else { | 3788 } else { |
3774 loop.Jump(); | 3789 loop.Jump(); |
3775 } | 3790 } |
(...skipping 3084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6860 | 6875 |
6861 Result new_value = frame_->Pop(); | 6876 Result new_value = frame_->Pop(); |
6862 new_value.ToRegister(); | 6877 new_value.ToRegister(); |
6863 | 6878 |
6864 Result old_value; // Only allocated in the postfix case. | 6879 Result old_value; // Only allocated in the postfix case. |
6865 if (is_postfix) { | 6880 if (is_postfix) { |
6866 // Allocate a temporary to preserve the old value. | 6881 // Allocate a temporary to preserve the old value. |
6867 old_value = allocator_->Allocate(); | 6882 old_value = allocator_->Allocate(); |
6868 ASSERT(old_value.is_valid()); | 6883 ASSERT(old_value.is_valid()); |
6869 __ mov(old_value.reg(), new_value.reg()); | 6884 __ mov(old_value.reg(), new_value.reg()); |
| 6885 |
| 6886 // The return value for postfix operations is the |
| 6887 // same as the input, and has the same number info. |
| 6888 old_value.set_number_info(new_value.number_info()); |
6870 } | 6889 } |
| 6890 |
6871 // Ensure the new value is writable. | 6891 // Ensure the new value is writable. |
6872 frame_->Spill(new_value.reg()); | 6892 frame_->Spill(new_value.reg()); |
6873 | 6893 |
6874 Result tmp; | 6894 Result tmp; |
6875 if (new_value.is_smi()) { | 6895 if (new_value.is_smi()) { |
6876 if (FLAG_debug_code) { | 6896 if (FLAG_debug_code) { |
6877 __ AbortIfNotSmi(new_value.reg(), "Operand not a smi"); | 6897 __ AbortIfNotSmi(new_value.reg(), "Operand not a smi"); |
6878 } | 6898 } |
6879 } else { | 6899 } else { |
6880 // We don't know statically if the input is a smi. | 6900 // We don't know statically if the input is a smi. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6924 deferred->Branch(not_zero); | 6944 deferred->Branch(not_zero); |
6925 } else { | 6945 } else { |
6926 // Otherwise we test separately for overflow and smi tag. | 6946 // Otherwise we test separately for overflow and smi tag. |
6927 deferred->Branch(overflow); | 6947 deferred->Branch(overflow); |
6928 __ test(new_value.reg(), Immediate(kSmiTagMask)); | 6948 __ test(new_value.reg(), Immediate(kSmiTagMask)); |
6929 deferred->Branch(not_zero); | 6949 deferred->Branch(not_zero); |
6930 } | 6950 } |
6931 } | 6951 } |
6932 deferred->BindExit(); | 6952 deferred->BindExit(); |
6933 | 6953 |
| 6954 // The result of ++ or -- is an Integer32 if the |
| 6955 // input is a smi. Otherwise it is a number. |
| 6956 if (new_value.is_smi()) { |
| 6957 new_value.set_number_info(NumberInfo::Integer32()); |
| 6958 } else { |
| 6959 new_value.set_number_info(NumberInfo::Number()); |
| 6960 } |
6934 | 6961 |
6935 // Postfix: store the old value in the allocated slot under the | 6962 // Postfix: store the old value in the allocated slot under the |
6936 // reference. | 6963 // reference. |
6937 if (is_postfix) frame_->SetElementAt(target.size(), &old_value); | 6964 if (is_postfix) frame_->SetElementAt(target.size(), &old_value); |
6938 | 6965 |
6939 frame_->Push(&new_value); | 6966 frame_->Push(&new_value); |
6940 // Non-constant: update the reference. | 6967 // Non-constant: update the reference. |
6941 if (!is_const) target.SetValue(NOT_CONST_INIT); | 6968 if (!is_const) target.SetValue(NOT_CONST_INIT); |
6942 } | 6969 } |
6943 | 6970 |
(...skipping 5276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12220 | 12247 |
12221 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 12248 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
12222 // tagged as a small integer. | 12249 // tagged as a small integer. |
12223 __ bind(&runtime); | 12250 __ bind(&runtime); |
12224 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 12251 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
12225 } | 12252 } |
12226 | 12253 |
12227 #undef __ | 12254 #undef __ |
12228 | 12255 |
12229 } } // namespace v8::internal | 12256 } } // namespace v8::internal |
OLD | NEW |