Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: src/codegen-ia32.cc

Issue 27130: Experimental: fix a bug in our handling of the short-circuit boolean... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/codegen-ia32.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 4603 matching lines...) Expand 10 before | Expand all | Expand 10 after
4614 // NOTE: If the left hand side produces a materialized value (not 4614 // NOTE: If the left hand side produces a materialized value (not
4615 // control flow), we force the right hand side to do the same. This 4615 // control flow), we force the right hand side to do the same. This
4616 // is necessary because we assume that if we get control flow on the 4616 // is necessary because we assume that if we get control flow on the
4617 // last path out of an expression we got it on all paths. 4617 // last path out of an expression we got it on all paths.
4618 if (op == Token::AND) { 4618 if (op == Token::AND) {
4619 JumpTarget is_true(this); 4619 JumpTarget is_true(this);
4620 ControlDestination dest(&is_true, destination()->false_target(), true); 4620 ControlDestination dest(&is_true, destination()->false_target(), true);
4621 LoadCondition(node->left(), NOT_INSIDE_TYPEOF, &dest, false); 4621 LoadCondition(node->left(), NOT_INSIDE_TYPEOF, &dest, false);
4622 4622
4623 if (dest.false_was_fall_through()) { 4623 if (dest.false_was_fall_through()) {
4624 // We have just bound the false target. There may be dangling 4624 // The current false target was used as the fall-through. If
4625 // jumps to is_true. 4625 // there are no dangling jumps to is_true then the left
4626 // subexpression was unconditionally false. Otherwise we have
4627 // paths where we do have to evaluate the right subexpression.
4626 if (is_true.is_linked()) { 4628 if (is_true.is_linked()) {
4627 destination()->false_target()->Unuse(); 4629 // We need to compile the right subexpression. If the jump to
4628 destination()->false_target()->Jump(); 4630 // the current false target was a forward jump then we have a
4631 // valid frame, we have just bound the false target, and we
4632 // have to jump around the code for the right subexpression.
4633 if (has_valid_frame()) {
4634 destination()->false_target()->Unuse();
4635 destination()->false_target()->Jump();
4636 }
4629 is_true.Bind(); 4637 is_true.Bind();
4630 destination()->Goto(true); 4638 // The left subexpression compiled to control flow, so the
4639 // right one is free to do so as well.
4640 LoadCondition(node->right(), NOT_INSIDE_TYPEOF, destination(), false);
4641 } else {
4642 // We have actually just jumped to or bound the current false
4643 // target but the current control destination is not marked as
4644 // used.
4645 destination()->Use(false);
4631 } 4646 }
4647
4632 } else if (dest.is_used()) { 4648 } else if (dest.is_used()) {
4633 // The first subexpression compiled to control flow (is_true was 4649 // The left subexpression compiled to control flow (and is_true
4634 // just bound), so the second is free to do so as well. 4650 // was just bound), so the right is free to do so as well.
4635 LoadCondition(node->right(), NOT_INSIDE_TYPEOF, destination(), false); 4651 LoadCondition(node->right(), NOT_INSIDE_TYPEOF, destination(), false);
4652
4636 } else { 4653 } else {
4637 // We have a materialized value on the frame, so we exit with 4654 // We have a materialized value on the frame, so we exit with
4638 // one on all paths. There are possibly also jumps to is_true 4655 // one on all paths. There are possibly also jumps to is_true
4639 // from nested subexpressions. 4656 // from nested subexpressions.
4640 JumpTarget pop_and_continue(this); 4657 JumpTarget pop_and_continue(this);
4641 JumpTarget exit(this); 4658 JumpTarget exit(this);
4642 4659
4643 // Avoid popping the result if it converts to 'false' using the 4660 // Avoid popping the result if it converts to 'false' using the
4644 // standard ToBoolean() conversion as described in ECMA-262, 4661 // standard ToBoolean() conversion as described in ECMA-262,
4645 // section 9.2, page 30. 4662 // section 9.2, page 30.
4646 // 4663 //
4647 // Duplicate the TOS value. The duplicate will be popped by 4664 // Duplicate the TOS value. The duplicate will be popped by
4648 // ToBoolean. 4665 // ToBoolean.
4649 frame_->Dup(); 4666 frame_->Dup();
4650 ControlDestination dest(&pop_and_continue, &exit, true); 4667 ControlDestination dest(&pop_and_continue, &exit, true);
4651 ToBoolean(&dest); 4668 ToBoolean(&dest);
4652 4669
4653 // Pop the result of evaluating the first part. 4670 // Pop the result of evaluating the first part.
4654 frame_->Drop(); 4671 frame_->Drop();
4655 4672
4656 // Evaluate right side expression. 4673 // Compile right side expression.
4657 is_true.Bind(); 4674 is_true.Bind();
4658 Load(node->right()); 4675 Load(node->right());
4659 4676
4660 // Exit (always with a materialized value). 4677 // Exit (always with a materialized value).
4661 exit.Bind(); 4678 exit.Bind();
4662 } 4679 }
4663 4680
4664 } else if (op == Token::OR) { 4681 } else if (op == Token::OR) {
4665 JumpTarget is_false(this); 4682 JumpTarget is_false(this);
4666 ControlDestination dest(destination()->true_target(), &is_false, false); 4683 ControlDestination dest(destination()->true_target(), &is_false, false);
4667 LoadCondition(node->left(), NOT_INSIDE_TYPEOF, &dest, false); 4684 LoadCondition(node->left(), NOT_INSIDE_TYPEOF, &dest, false);
4668 4685
4669 if (dest.true_was_fall_through()) { 4686 if (dest.true_was_fall_through()) {
4670 // We have just bound the true target. There may be dangling 4687 // The current true target was used as the fall-through. If
4671 // jumps to is_false. 4688 // there are no dangling jumps to is_false then the left
4689 // subexpression was unconditionally true. Otherwise we have
4690 // paths where we do have to evaluate the right subexpression.
4672 if (is_false.is_linked()) { 4691 if (is_false.is_linked()) {
4673 destination()->true_target()->Unuse(); 4692 // We need to compile the right subexpression. If the jump to
4674 destination()->true_target()->Jump(); 4693 // the current true target was a forward jump then we have a
4694 // valid frame, we have just bound the true target, and we
4695 // have to jump around the code for the right subexpression.
4696 if (has_valid_frame()) {
4697 destination()->true_target()->Unuse();
4698 destination()->true_target()->Jump();
4699 }
4675 is_false.Bind(); 4700 is_false.Bind();
4676 destination()->Goto(false); 4701 // The left subexpression compiled to control flow, so the
4702 // right one is free to do so as well.
4703 LoadCondition(node->right(), NOT_INSIDE_TYPEOF, destination(), false);
4704 } else {
4705 // We have just jumped to or bound the current true target but
4706 // the current control destination is not marked as used.
4707 destination()->Use(true);
4677 } 4708 }
4709
4678 } else if (dest.is_used()) { 4710 } else if (dest.is_used()) {
4679 // The first subexpression compiled to control flow (is_false 4711 // The left subexpression compiled to control flow (and is_false
4680 // was just bound), so the second is free to do so as well. 4712 // was just bound), so the right is free to do so as well.
4681 LoadCondition(node->right(), NOT_INSIDE_TYPEOF, destination(), false); 4713 LoadCondition(node->right(), NOT_INSIDE_TYPEOF, destination(), false);
4714
4682 } else { 4715 } else {
4683 // We have a materialized value on the frame, so we exit with 4716 // We have a materialized value on the frame, so we exit with
4684 // one on all paths. There are possibly also jumps to is_false 4717 // one on all paths. There are possibly also jumps to is_false
4685 // from nested subexpressions. 4718 // from nested subexpressions.
4686 JumpTarget pop_and_continue(this); 4719 JumpTarget pop_and_continue(this);
4687 JumpTarget exit(this); 4720 JumpTarget exit(this);
4688 4721
4689 // Avoid popping the result if it converts to 'true' using the 4722 // Avoid popping the result if it converts to 'true' using the
4690 // standard ToBoolean() conversion as described in ECMA-262, 4723 // standard ToBoolean() conversion as described in ECMA-262,
4691 // section 9.2, page 30. 4724 // section 9.2, page 30.
4692 // 4725 //
4693 // Duplicate the TOS value. The duplicate will be popped by 4726 // Duplicate the TOS value. The duplicate will be popped by
4694 // ToBoolean. 4727 // ToBoolean.
4695 frame_->Dup(); 4728 frame_->Dup();
4696 ControlDestination dest(&exit, &pop_and_continue, false); 4729 ControlDestination dest(&exit, &pop_and_continue, false);
4697 ToBoolean(&dest); 4730 ToBoolean(&dest);
4698 4731
4699 // Pop the result of evaluating the first part. 4732 // Pop the result of evaluating the first part.
4700 frame_->Drop(); 4733 frame_->Drop();
4701 4734
4702 // Evaluate right side expression. 4735 // Compile right side expression.
4703 is_false.Bind(); 4736 is_false.Bind();
4704 Load(node->right()); 4737 Load(node->right());
4705 4738
4706 // Exit (always with a materialized value). 4739 // Exit (always with a materialized value).
4707 exit.Bind(); 4740 exit.Bind();
4708 } 4741 }
4709 4742
4710 } else { 4743 } else {
4711 // NOTE: The code below assumes that the slow cases (calls to runtime) 4744 // NOTE: The code below assumes that the slow cases (calls to runtime)
4712 // never return a constant/immutable object. 4745 // never return a constant/immutable object.
(...skipping 2015 matching lines...) Expand 10 before | Expand all | Expand 10 after
6728 6761
6729 // Slow-case: Go through the JavaScript implementation. 6762 // Slow-case: Go through the JavaScript implementation.
6730 __ bind(&slow); 6763 __ bind(&slow);
6731 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 6764 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
6732 } 6765 }
6733 6766
6734 6767
6735 #undef __ 6768 #undef __
6736 6769
6737 } } // namespace v8::internal 6770 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698