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 |