| 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 3978 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3989     frame_->EmitPush(r0); | 3989     frame_->EmitPush(r0); | 
| 3990     if (!is_const) target.SetValue(NOT_CONST_INIT); | 3990     if (!is_const) target.SetValue(NOT_CONST_INIT); | 
| 3991   } | 3991   } | 
| 3992 | 3992 | 
| 3993   // Postfix: Discard the new value and use the old. | 3993   // Postfix: Discard the new value and use the old. | 
| 3994   if (is_postfix) frame_->EmitPop(r0); | 3994   if (is_postfix) frame_->EmitPop(r0); | 
| 3995   ASSERT(frame_->height() == original_height + 1); | 3995   ASSERT(frame_->height() == original_height + 1); | 
| 3996 } | 3996 } | 
| 3997 | 3997 | 
| 3998 | 3998 | 
| 3999 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { | 3999 void CodeGenerator::GenerateLogicalBooleanOperation(BinaryOperation* node) { | 
| 4000 #ifdef DEBUG |  | 
| 4001   int original_height = frame_->height(); |  | 
| 4002 #endif |  | 
| 4003   VirtualFrame::SpilledScope spilled_scope; |  | 
| 4004   Comment cmnt(masm_, "[ BinaryOperation"); |  | 
| 4005   Token::Value op = node->op(); |  | 
| 4006 |  | 
| 4007   // According to ECMA-262 section 11.11, page 58, the binary logical | 4000   // According to ECMA-262 section 11.11, page 58, the binary logical | 
| 4008   // operators must yield the result of one of the two expressions | 4001   // operators must yield the result of one of the two expressions | 
| 4009   // before any ToBoolean() conversions. This means that the value | 4002   // before any ToBoolean() conversions. This means that the value | 
| 4010   // produced by a && or || operator is not necessarily a boolean. | 4003   // produced by a && or || operator is not necessarily a boolean. | 
| 4011 | 4004 | 
| 4012   // NOTE: If the left hand side produces a materialized value (not in | 4005   // NOTE: If the left hand side produces a materialized value (not in | 
| 4013   // the CC register), we force the right hand side to do the | 4006   // the CC register), we force the right hand side to do the | 
| 4014   // same. This is necessary because we may have to branch to the exit | 4007   // same. This is necessary because we may have to branch to the exit | 
| 4015   // after evaluating the left hand side (due to the shortcut | 4008   // after evaluating the left hand side (due to the shortcut | 
| 4016   // semantics), but the compiler must (statically) know if the result | 4009   // semantics), but the compiler must (statically) know if the result | 
| 4017   // of compiling the binary operation is materialized or not. | 4010   // of compiling the binary operation is materialized or not. | 
| 4018 | 4011   if (node->op() == Token::AND) { | 
| 4019   if (op == Token::AND) { |  | 
| 4020     JumpTarget is_true; | 4012     JumpTarget is_true; | 
| 4021     LoadConditionAndSpill(node->left(), | 4013     LoadConditionAndSpill(node->left(), | 
| 4022                           &is_true, | 4014                           &is_true, | 
| 4023                           false_target(), | 4015                           false_target(), | 
| 4024                           false); | 4016                           false); | 
| 4025     if (has_valid_frame() && !has_cc()) { | 4017     if (has_valid_frame() && !has_cc()) { | 
| 4026       // The left-hand side result is on top of the virtual frame. | 4018       // The left-hand side result is on top of the virtual frame. | 
| 4027       JumpTarget pop_and_continue; | 4019       JumpTarget pop_and_continue; | 
| 4028       JumpTarget exit; | 4020       JumpTarget exit; | 
| 4029 | 4021 | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 4055       is_true.Bind(); | 4047       is_true.Bind(); | 
| 4056       LoadConditionAndSpill(node->right(), | 4048       LoadConditionAndSpill(node->right(), | 
| 4057                             true_target(), | 4049                             true_target(), | 
| 4058                             false_target(), | 4050                             false_target(), | 
| 4059                             false); | 4051                             false); | 
| 4060     } else { | 4052     } else { | 
| 4061       // Nothing to do. | 4053       // Nothing to do. | 
| 4062       ASSERT(!has_valid_frame() && !has_cc() && !is_true.is_linked()); | 4054       ASSERT(!has_valid_frame() && !has_cc() && !is_true.is_linked()); | 
| 4063     } | 4055     } | 
| 4064 | 4056 | 
| 4065   } else if (op == Token::OR) { | 4057   } else { | 
|  | 4058     ASSERT(node->op() == Token::OR); | 
| 4066     JumpTarget is_false; | 4059     JumpTarget is_false; | 
| 4067     LoadConditionAndSpill(node->left(), | 4060     LoadConditionAndSpill(node->left(), | 
| 4068                           true_target(), | 4061                           true_target(), | 
| 4069                           &is_false, | 4062                           &is_false, | 
| 4070                           false); | 4063                           false); | 
| 4071     if (has_valid_frame() && !has_cc()) { | 4064     if (has_valid_frame() && !has_cc()) { | 
| 4072       // The left-hand side result is on top of the virtual frame. | 4065       // The left-hand side result is on top of the virtual frame. | 
| 4073       JumpTarget pop_and_continue; | 4066       JumpTarget pop_and_continue; | 
| 4074       JumpTarget exit; | 4067       JumpTarget exit; | 
| 4075 | 4068 | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 4100       } | 4093       } | 
| 4101       is_false.Bind(); | 4094       is_false.Bind(); | 
| 4102       LoadConditionAndSpill(node->right(), | 4095       LoadConditionAndSpill(node->right(), | 
| 4103                             true_target(), | 4096                             true_target(), | 
| 4104                             false_target(), | 4097                             false_target(), | 
| 4105                             false); | 4098                             false); | 
| 4106     } else { | 4099     } else { | 
| 4107       // Nothing to do. | 4100       // Nothing to do. | 
| 4108       ASSERT(!has_valid_frame() && !has_cc() && !is_false.is_linked()); | 4101       ASSERT(!has_valid_frame() && !has_cc() && !is_false.is_linked()); | 
| 4109     } | 4102     } | 
|  | 4103   } | 
|  | 4104 } | 
| 4110 | 4105 | 
|  | 4106 | 
|  | 4107 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { | 
|  | 4108 #ifdef DEBUG | 
|  | 4109   int original_height = frame_->height(); | 
|  | 4110 #endif | 
|  | 4111   VirtualFrame::SpilledScope spilled_scope; | 
|  | 4112   Comment cmnt(masm_, "[ BinaryOperation"); | 
|  | 4113 | 
|  | 4114   if (node->op() == Token::AND || node->op() == Token::OR) { | 
|  | 4115     GenerateLogicalBooleanOperation(node); | 
| 4111   } else { | 4116   } else { | 
| 4112     // Optimize for the case where (at least) one of the expressions | 4117     // Optimize for the case where (at least) one of the expressions | 
| 4113     // is a literal small integer. | 4118     // is a literal small integer. | 
| 4114     Literal* lliteral = node->left()->AsLiteral(); | 4119     Literal* lliteral = node->left()->AsLiteral(); | 
| 4115     Literal* rliteral = node->right()->AsLiteral(); | 4120     Literal* rliteral = node->right()->AsLiteral(); | 
| 4116     // NOTE: The code below assumes that the slow cases (calls to runtime) | 4121     // NOTE: The code below assumes that the slow cases (calls to runtime) | 
| 4117     // never return a constant/immutable object. | 4122     // never return a constant/immutable object. | 
| 4118     bool overwrite_left = | 4123     bool overwrite_left = | 
| 4119         (node->left()->AsBinaryOperation() != NULL && | 4124         (node->left()->AsBinaryOperation() != NULL && | 
| 4120          node->left()->AsBinaryOperation()->ResultOverwriteAllowed()); | 4125          node->left()->AsBinaryOperation()->ResultOverwriteAllowed()); | 
| (...skipping 3828 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 7949 | 7954 | 
| 7950   // Just jump to runtime to add the two strings. | 7955   // Just jump to runtime to add the two strings. | 
| 7951   __ bind(&string_add_runtime); | 7956   __ bind(&string_add_runtime); | 
| 7952   __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 7957   __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 
| 7953 } | 7958 } | 
| 7954 | 7959 | 
| 7955 | 7960 | 
| 7956 #undef __ | 7961 #undef __ | 
| 7957 | 7962 | 
| 7958 } }  // namespace v8::internal | 7963 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|