| 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 3263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3274 frame_->Push(&new_value); | 3274 frame_->Push(&new_value); |
| 3275 // Non-constant: update the reference. | 3275 // Non-constant: update the reference. |
| 3276 if (!is_const) target.SetValue(NOT_CONST_INIT); | 3276 if (!is_const) target.SetValue(NOT_CONST_INIT); |
| 3277 } | 3277 } |
| 3278 | 3278 |
| 3279 // Postfix: drop the new value and use the old. | 3279 // Postfix: drop the new value and use the old. |
| 3280 if (is_postfix) frame_->Drop(); | 3280 if (is_postfix) frame_->Drop(); |
| 3281 } | 3281 } |
| 3282 | 3282 |
| 3283 | 3283 |
| 3284 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { | 3284 void CodeGenerator::GenerateLogicalBooleanOperation(BinaryOperation* node) { |
| 3285 // TODO(X64): This code was copied verbatim from codegen-ia32. | |
| 3286 // Either find a reason to change it or move it to a shared location. | |
| 3287 | |
| 3288 Comment cmnt(masm_, "[ BinaryOperation"); | |
| 3289 Token::Value op = node->op(); | |
| 3290 | |
| 3291 // According to ECMA-262 section 11.11, page 58, the binary logical | 3285 // According to ECMA-262 section 11.11, page 58, the binary logical |
| 3292 // operators must yield the result of one of the two expressions | 3286 // operators must yield the result of one of the two expressions |
| 3293 // before any ToBoolean() conversions. This means that the value | 3287 // before any ToBoolean() conversions. This means that the value |
| 3294 // produced by a && or || operator is not necessarily a boolean. | 3288 // produced by a && or || operator is not necessarily a boolean. |
| 3295 | 3289 |
| 3296 // NOTE: If the left hand side produces a materialized value (not | 3290 // NOTE: If the left hand side produces a materialized value (not |
| 3297 // control flow), we force the right hand side to do the same. This | 3291 // control flow), we force the right hand side to do the same. This |
| 3298 // is necessary because we assume that if we get control flow on the | 3292 // is necessary because we assume that if we get control flow on the |
| 3299 // last path out of an expression we got it on all paths. | 3293 // last path out of an expression we got it on all paths. |
| 3300 if (op == Token::AND) { | 3294 if (node->op() == Token::AND) { |
| 3301 JumpTarget is_true; | 3295 JumpTarget is_true; |
| 3302 ControlDestination dest(&is_true, destination()->false_target(), true); | 3296 ControlDestination dest(&is_true, destination()->false_target(), true); |
| 3303 LoadCondition(node->left(), &dest, false); | 3297 LoadCondition(node->left(), &dest, false); |
| 3304 | 3298 |
| 3305 if (dest.false_was_fall_through()) { | 3299 if (dest.false_was_fall_through()) { |
| 3306 // The current false target was used as the fall-through. If | 3300 // The current false target was used as the fall-through. If |
| 3307 // there are no dangling jumps to is_true then the left | 3301 // there are no dangling jumps to is_true then the left |
| 3308 // subexpression was unconditionally false. Otherwise we have | 3302 // subexpression was unconditionally false. Otherwise we have |
| 3309 // paths where we do have to evaluate the right subexpression. | 3303 // paths where we do have to evaluate the right subexpression. |
| 3310 if (is_true.is_linked()) { | 3304 if (is_true.is_linked()) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3353 frame_->Drop(); | 3347 frame_->Drop(); |
| 3354 | 3348 |
| 3355 // Compile right side expression. | 3349 // Compile right side expression. |
| 3356 is_true.Bind(); | 3350 is_true.Bind(); |
| 3357 Load(node->right()); | 3351 Load(node->right()); |
| 3358 | 3352 |
| 3359 // Exit (always with a materialized value). | 3353 // Exit (always with a materialized value). |
| 3360 exit.Bind(); | 3354 exit.Bind(); |
| 3361 } | 3355 } |
| 3362 | 3356 |
| 3363 } else if (op == Token::OR) { | 3357 } else { |
| 3358 ASSERT(node->op() == Token::OR); |
| 3364 JumpTarget is_false; | 3359 JumpTarget is_false; |
| 3365 ControlDestination dest(destination()->true_target(), &is_false, false); | 3360 ControlDestination dest(destination()->true_target(), &is_false, false); |
| 3366 LoadCondition(node->left(), &dest, false); | 3361 LoadCondition(node->left(), &dest, false); |
| 3367 | 3362 |
| 3368 if (dest.true_was_fall_through()) { | 3363 if (dest.true_was_fall_through()) { |
| 3369 // The current true target was used as the fall-through. If | 3364 // The current true target was used as the fall-through. If |
| 3370 // there are no dangling jumps to is_false then the left | 3365 // there are no dangling jumps to is_false then the left |
| 3371 // subexpression was unconditionally true. Otherwise we have | 3366 // subexpression was unconditionally true. Otherwise we have |
| 3372 // paths where we do have to evaluate the right subexpression. | 3367 // paths where we do have to evaluate the right subexpression. |
| 3373 if (is_false.is_linked()) { | 3368 if (is_false.is_linked()) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3414 // Pop the result of evaluating the first part. | 3409 // Pop the result of evaluating the first part. |
| 3415 frame_->Drop(); | 3410 frame_->Drop(); |
| 3416 | 3411 |
| 3417 // Compile right side expression. | 3412 // Compile right side expression. |
| 3418 is_false.Bind(); | 3413 is_false.Bind(); |
| 3419 Load(node->right()); | 3414 Load(node->right()); |
| 3420 | 3415 |
| 3421 // Exit (always with a materialized value). | 3416 // Exit (always with a materialized value). |
| 3422 exit.Bind(); | 3417 exit.Bind(); |
| 3423 } | 3418 } |
| 3419 } |
| 3420 } |
| 3424 | 3421 |
| 3422 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { |
| 3423 Comment cmnt(masm_, "[ BinaryOperation"); |
| 3424 |
| 3425 if (node->op() == Token::AND || node->op() == Token::OR) { |
| 3426 GenerateLogicalBooleanOperation(node); |
| 3425 } else { | 3427 } else { |
| 3426 // NOTE: The code below assumes that the slow cases (calls to runtime) | 3428 // NOTE: The code below assumes that the slow cases (calls to runtime) |
| 3427 // never return a constant/immutable object. | 3429 // never return a constant/immutable object. |
| 3428 OverwriteMode overwrite_mode = NO_OVERWRITE; | 3430 OverwriteMode overwrite_mode = NO_OVERWRITE; |
| 3429 if (node->left()->AsBinaryOperation() != NULL && | 3431 if (node->left()->AsBinaryOperation() != NULL && |
| 3430 node->left()->AsBinaryOperation()->ResultOverwriteAllowed()) { | 3432 node->left()->AsBinaryOperation()->ResultOverwriteAllowed()) { |
| 3431 overwrite_mode = OVERWRITE_LEFT; | 3433 overwrite_mode = OVERWRITE_LEFT; |
| 3432 } else if (node->right()->AsBinaryOperation() != NULL && | 3434 } else if (node->right()->AsBinaryOperation() != NULL && |
| 3433 node->right()->AsBinaryOperation()->ResultOverwriteAllowed()) { | 3435 node->right()->AsBinaryOperation()->ResultOverwriteAllowed()) { |
| 3434 overwrite_mode = OVERWRITE_RIGHT; | 3436 overwrite_mode = OVERWRITE_RIGHT; |
| (...skipping 6556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9991 // Call the function from C++. | 9993 // Call the function from C++. |
| 9992 return FUNCTION_CAST<ModuloFunction>(buffer); | 9994 return FUNCTION_CAST<ModuloFunction>(buffer); |
| 9993 } | 9995 } |
| 9994 | 9996 |
| 9995 #endif | 9997 #endif |
| 9996 | 9998 |
| 9997 | 9999 |
| 9998 #undef __ | 10000 #undef __ |
| 9999 | 10001 |
| 10000 } } // namespace v8::internal | 10002 } } // namespace v8::internal |
| OLD | NEW |