Index: src/interpreter/bytecode-array-builder.cc |
diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc |
index 9be1f0ec908ca094e62259e80ff4e16843e5d9c5..e34c6337b18db291a2c44ac3ad54dd0c1cf22617 100644 |
--- a/src/interpreter/bytecode-array-builder.cc |
+++ b/src/interpreter/bytecode-array-builder.cc |
@@ -480,33 +480,43 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { |
} |
+bool BytecodeArrayBuilder::NeedToBooleanCast() { |
+ if (!LastBytecodeInSameBlock()) { |
+ // If the previous bytecode was from a different block return false. |
+ return true; |
+ } |
+ |
+ // If the previous bytecode puts a boolean in the accumulator return true. |
+ switch (Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_))) { |
+ case Bytecode::kToBoolean: |
+ UNREACHABLE(); |
+ case Bytecode::kLdaTrue: |
+ case Bytecode::kLdaFalse: |
+ case Bytecode::kLogicalNot: |
+ case Bytecode::kTestEqual: |
+ case Bytecode::kTestNotEqual: |
+ case Bytecode::kTestEqualStrict: |
+ case Bytecode::kTestNotEqualStrict: |
+ case Bytecode::kTestLessThan: |
+ case Bytecode::kTestLessThanOrEqual: |
+ case Bytecode::kTestGreaterThan: |
+ case Bytecode::kTestGreaterThanOrEqual: |
+ case Bytecode::kTestInstanceOf: |
+ case Bytecode::kTestIn: |
+ case Bytecode::kForInDone: |
+ return false; |
+ default: |
+ return true; |
+ } |
+} |
+ |
+ |
BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() { |
- if (LastBytecodeInSameBlock()) { |
- // If the previous bytecode puts a boolean in the accumulator |
- // there is no need to emit an instruction. |
- switch (Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_))) { |
- case Bytecode::kToBoolean: |
- UNREACHABLE(); |
- case Bytecode::kLdaTrue: |
- case Bytecode::kLdaFalse: |
- case Bytecode::kLogicalNot: |
- case Bytecode::kTestEqual: |
- case Bytecode::kTestNotEqual: |
- case Bytecode::kTestEqualStrict: |
- case Bytecode::kTestNotEqualStrict: |
- case Bytecode::kTestLessThan: |
- case Bytecode::kTestLessThanOrEqual: |
- case Bytecode::kTestGreaterThan: |
- case Bytecode::kTestGreaterThanOrEqual: |
- case Bytecode::kTestInstanceOf: |
- case Bytecode::kTestIn: |
- return *this; |
- default: |
- // Fall through to output kToBoolean. |
- break; |
- } |
+ // If the previous bytecode puts a boolean in the accumulator |
+ // there is no need to emit an instruction. |
+ if (NeedToBooleanCast()) { |
+ Output(Bytecode::kToBoolean); |
} |
- Output(Bytecode::kToBoolean); |
return *this; |
} |
@@ -613,8 +623,32 @@ void BytecodeArrayBuilder::PatchJump( |
} |
+// static |
+Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode) { |
+ switch (jump_bytecode) { |
+ case Bytecode::kJump: |
+ case Bytecode::kJumpIfNull: |
+ case Bytecode::kJumpIfUndefined: |
+ return jump_bytecode; |
+ case Bytecode::kJumpIfTrue: |
+ return Bytecode::kJumpIfToBooleanTrue; |
+ case Bytecode::kJumpIfFalse: |
+ return Bytecode::kJumpIfToBooleanFalse; |
+ default: |
+ UNREACHABLE(); |
+ } |
+ return static_cast<Bytecode>(-1); |
+} |
+ |
+ |
BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, |
BytecodeLabel* label) { |
+ // Check if the value in accumulator is boolean, if not choose an |
+ // appropriate JumpIfToBoolean bytecode. |
+ if (NeedToBooleanCast()) { |
+ jump_bytecode = GetJumpWithToBoolean(jump_bytecode); |
+ } |
+ |
int delta; |
if (label->is_bound()) { |
// Label has been bound already so this is a backwards jump. |
@@ -659,18 +693,6 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { |
} |
-BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfToBooleanTrue( |
- BytecodeLabel* label) { |
- return OutputJump(Bytecode::kJumpIfToBooleanTrue, label); |
-} |
- |
- |
-BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfToBooleanFalse( |
- BytecodeLabel* label) { |
- return OutputJump(Bytecode::kJumpIfToBooleanFalse, label); |
-} |
- |
- |
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { |
return OutputJump(Bytecode::kJumpIfNull, label); |
} |