| 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 |