OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 3719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3730 __ mov(arg_count.reg(), Operand(0)); // not counting receiver | 3730 __ mov(arg_count.reg(), Operand(0)); // not counting receiver |
3731 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1); | 3731 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1); |
3732 continue_label.Bind(); | 3732 continue_label.Bind(); |
3733 break; | 3733 break; |
3734 } | 3734 } |
3735 default: | 3735 default: |
3736 UNREACHABLE(); | 3736 UNREACHABLE(); |
3737 } | 3737 } |
3738 frame_->EmitPush(r0); // r0 has result | 3738 frame_->EmitPush(r0); // r0 has result |
3739 } | 3739 } |
3740 ASSERT((has_cc() && frame_->height() == original_height) || | 3740 ASSERT(!has_valid_frame() || |
| 3741 (has_cc() && frame_->height() == original_height) || |
3741 (!has_cc() && frame_->height() == original_height + 1)); | 3742 (!has_cc() && frame_->height() == original_height + 1)); |
3742 } | 3743 } |
3743 | 3744 |
3744 | 3745 |
3745 void CodeGenerator::VisitCountOperation(CountOperation* node) { | 3746 void CodeGenerator::VisitCountOperation(CountOperation* node) { |
3746 #ifdef DEBUG | 3747 #ifdef DEBUG |
3747 int original_height = frame_->height(); | 3748 int original_height = frame_->height(); |
3748 #endif | 3749 #endif |
3749 VirtualFrame::SpilledScope spilled_scope; | 3750 VirtualFrame::SpilledScope spilled_scope; |
3750 Comment cmnt(masm_, "[ CountOperation"); | 3751 Comment cmnt(masm_, "[ CountOperation"); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3864 // semantics), but the compiler must (statically) know if the result | 3865 // semantics), but the compiler must (statically) know if the result |
3865 // of compiling the binary operation is materialized or not. | 3866 // of compiling the binary operation is materialized or not. |
3866 | 3867 |
3867 if (op == Token::AND) { | 3868 if (op == Token::AND) { |
3868 JumpTarget is_true; | 3869 JumpTarget is_true; |
3869 LoadConditionAndSpill(node->left(), | 3870 LoadConditionAndSpill(node->left(), |
3870 NOT_INSIDE_TYPEOF, | 3871 NOT_INSIDE_TYPEOF, |
3871 &is_true, | 3872 &is_true, |
3872 false_target(), | 3873 false_target(), |
3873 false); | 3874 false); |
3874 if (has_cc()) { | 3875 if (has_valid_frame() && !has_cc()) { |
3875 Branch(false, false_target()); | 3876 // The left-hand side result is on top of the virtual frame. |
3876 | |
3877 // Evaluate right side expression. | |
3878 is_true.Bind(); | |
3879 LoadConditionAndSpill(node->right(), | |
3880 NOT_INSIDE_TYPEOF, | |
3881 true_target(), | |
3882 false_target(), | |
3883 false); | |
3884 | |
3885 } else { | |
3886 JumpTarget pop_and_continue; | 3877 JumpTarget pop_and_continue; |
3887 JumpTarget exit; | 3878 JumpTarget exit; |
3888 | 3879 |
3889 __ ldr(r0, frame_->Top()); // dup the stack top | 3880 __ ldr(r0, frame_->Top()); // Duplicate the stack top. |
3890 frame_->EmitPush(r0); | 3881 frame_->EmitPush(r0); |
3891 // Avoid popping the result if it converts to 'false' using the | 3882 // Avoid popping the result if it converts to 'false' using the |
3892 // standard ToBoolean() conversion as described in ECMA-262, | 3883 // standard ToBoolean() conversion as described in ECMA-262, |
3893 // section 9.2, page 30. | 3884 // section 9.2, page 30. |
3894 ToBoolean(&pop_and_continue, &exit); | 3885 ToBoolean(&pop_and_continue, &exit); |
3895 Branch(false, &exit); | 3886 Branch(false, &exit); |
3896 | 3887 |
3897 // Pop the result of evaluating the first part. | 3888 // Pop the result of evaluating the first part. |
3898 pop_and_continue.Bind(); | 3889 pop_and_continue.Bind(); |
3899 frame_->EmitPop(r0); | 3890 frame_->EmitPop(r0); |
3900 | 3891 |
3901 // Evaluate right side expression. | 3892 // Evaluate right side expression. |
3902 is_true.Bind(); | 3893 is_true.Bind(); |
3903 LoadAndSpill(node->right()); | 3894 LoadAndSpill(node->right()); |
3904 | 3895 |
3905 // Exit (always with a materialized value). | 3896 // Exit (always with a materialized value). |
3906 exit.Bind(); | 3897 exit.Bind(); |
| 3898 } else if (has_cc() || is_true.is_linked()) { |
| 3899 // The left-hand side is either (a) partially compiled to |
| 3900 // control flow with a final branch left to emit or (b) fully |
| 3901 // compiled to control flow and possibly true. |
| 3902 if (has_cc()) { |
| 3903 Branch(false, false_target()); |
| 3904 } |
| 3905 is_true.Bind(); |
| 3906 LoadConditionAndSpill(node->right(), |
| 3907 NOT_INSIDE_TYPEOF, |
| 3908 true_target(), |
| 3909 false_target(), |
| 3910 false); |
| 3911 } else { |
| 3912 // Nothing to do. |
| 3913 ASSERT(!has_valid_frame() && !has_cc() && !is_true.is_linked()); |
3907 } | 3914 } |
3908 | 3915 |
3909 } else if (op == Token::OR) { | 3916 } else if (op == Token::OR) { |
3910 JumpTarget is_false; | 3917 JumpTarget is_false; |
3911 LoadConditionAndSpill(node->left(), | 3918 LoadConditionAndSpill(node->left(), |
3912 NOT_INSIDE_TYPEOF, | 3919 NOT_INSIDE_TYPEOF, |
3913 true_target(), | 3920 true_target(), |
3914 &is_false, | 3921 &is_false, |
3915 false); | 3922 false); |
3916 if (has_cc()) { | 3923 if (has_valid_frame() && !has_cc()) { |
3917 Branch(true, true_target()); | 3924 // The left-hand side result is on top of the virtual frame. |
3918 | |
3919 // Evaluate right side expression. | |
3920 is_false.Bind(); | |
3921 LoadConditionAndSpill(node->right(), | |
3922 NOT_INSIDE_TYPEOF, | |
3923 true_target(), | |
3924 false_target(), | |
3925 false); | |
3926 | |
3927 } else { | |
3928 JumpTarget pop_and_continue; | 3925 JumpTarget pop_and_continue; |
3929 JumpTarget exit; | 3926 JumpTarget exit; |
3930 | 3927 |
3931 __ ldr(r0, frame_->Top()); | 3928 __ ldr(r0, frame_->Top()); |
3932 frame_->EmitPush(r0); | 3929 frame_->EmitPush(r0); |
3933 // Avoid popping the result if it converts to 'true' using the | 3930 // Avoid popping the result if it converts to 'true' using the |
3934 // standard ToBoolean() conversion as described in ECMA-262, | 3931 // standard ToBoolean() conversion as described in ECMA-262, |
3935 // section 9.2, page 30. | 3932 // section 9.2, page 30. |
3936 ToBoolean(&exit, &pop_and_continue); | 3933 ToBoolean(&exit, &pop_and_continue); |
3937 Branch(true, &exit); | 3934 Branch(true, &exit); |
3938 | 3935 |
3939 // Pop the result of evaluating the first part. | 3936 // Pop the result of evaluating the first part. |
3940 pop_and_continue.Bind(); | 3937 pop_and_continue.Bind(); |
3941 frame_->EmitPop(r0); | 3938 frame_->EmitPop(r0); |
3942 | 3939 |
3943 // Evaluate right side expression. | 3940 // Evaluate right side expression. |
3944 is_false.Bind(); | 3941 is_false.Bind(); |
3945 LoadAndSpill(node->right()); | 3942 LoadAndSpill(node->right()); |
3946 | 3943 |
3947 // Exit (always with a materialized value). | 3944 // Exit (always with a materialized value). |
3948 exit.Bind(); | 3945 exit.Bind(); |
| 3946 } else if (has_cc() || is_false.is_linked()) { |
| 3947 // The left-hand side is either (a) partially compiled to |
| 3948 // control flow with a final branch left to emit or (b) fully |
| 3949 // compiled to control flow and possibly false. |
| 3950 if (has_cc()) { |
| 3951 Branch(true, true_target()); |
| 3952 } |
| 3953 is_false.Bind(); |
| 3954 LoadConditionAndSpill(node->right(), |
| 3955 NOT_INSIDE_TYPEOF, |
| 3956 true_target(), |
| 3957 false_target(), |
| 3958 false); |
| 3959 } else { |
| 3960 // Nothing to do. |
| 3961 ASSERT(!has_valid_frame() && !has_cc() && !is_false.is_linked()); |
3949 } | 3962 } |
3950 | 3963 |
3951 } else { | 3964 } else { |
3952 // Optimize for the case where (at least) one of the expressions | 3965 // Optimize for the case where (at least) one of the expressions |
3953 // is a literal small integer. | 3966 // is a literal small integer. |
3954 Literal* lliteral = node->left()->AsLiteral(); | 3967 Literal* lliteral = node->left()->AsLiteral(); |
3955 Literal* rliteral = node->right()->AsLiteral(); | 3968 Literal* rliteral = node->right()->AsLiteral(); |
3956 // NOTE: The code below assumes that the slow cases (calls to runtime) | 3969 // NOTE: The code below assumes that the slow cases (calls to runtime) |
3957 // never return a constant/immutable object. | 3970 // never return a constant/immutable object. |
3958 bool overwrite_left = | 3971 bool overwrite_left = |
(...skipping 23 matching lines...) Expand all Loading... |
3982 overwrite_mode = OVERWRITE_LEFT; | 3995 overwrite_mode = OVERWRITE_LEFT; |
3983 } else if (overwrite_right) { | 3996 } else if (overwrite_right) { |
3984 overwrite_mode = OVERWRITE_RIGHT; | 3997 overwrite_mode = OVERWRITE_RIGHT; |
3985 } | 3998 } |
3986 LoadAndSpill(node->left()); | 3999 LoadAndSpill(node->left()); |
3987 LoadAndSpill(node->right()); | 4000 LoadAndSpill(node->right()); |
3988 GenericBinaryOperation(node->op(), overwrite_mode); | 4001 GenericBinaryOperation(node->op(), overwrite_mode); |
3989 } | 4002 } |
3990 frame_->EmitPush(r0); | 4003 frame_->EmitPush(r0); |
3991 } | 4004 } |
3992 ASSERT((has_cc() && frame_->height() == original_height) || | 4005 ASSERT(!has_valid_frame() || |
| 4006 (has_cc() && frame_->height() == original_height) || |
3993 (!has_cc() && frame_->height() == original_height + 1)); | 4007 (!has_cc() && frame_->height() == original_height + 1)); |
3994 } | 4008 } |
3995 | 4009 |
3996 | 4010 |
3997 void CodeGenerator::VisitThisFunction(ThisFunction* node) { | 4011 void CodeGenerator::VisitThisFunction(ThisFunction* node) { |
3998 #ifdef DEBUG | 4012 #ifdef DEBUG |
3999 int original_height = frame_->height(); | 4013 int original_height = frame_->height(); |
4000 #endif | 4014 #endif |
4001 VirtualFrame::SpilledScope spilled_scope; | 4015 VirtualFrame::SpilledScope spilled_scope; |
4002 __ ldr(r0, frame_->Function()); | 4016 __ ldr(r0, frame_->Function()); |
(...skipping 2399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6402 int CompareStub::MinorKey() { | 6416 int CompareStub::MinorKey() { |
6403 // Encode the two parameters in a unique 16 bit value. | 6417 // Encode the two parameters in a unique 16 bit value. |
6404 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); | 6418 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); |
6405 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); | 6419 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); |
6406 } | 6420 } |
6407 | 6421 |
6408 | 6422 |
6409 #undef __ | 6423 #undef __ |
6410 | 6424 |
6411 } } // namespace v8::internal | 6425 } } // namespace v8::internal |
OLD | NEW |