Index: src/interpreter/bytecode-array-builder.cc |
diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc |
index 2ce9d51377571c58f027bc3e3f07ff983e4e0eee..8f2d36f91368a52276788eeb33ca88414b75be1e 100644 |
--- a/src/interpreter/bytecode-array-builder.cc |
+++ b/src/interpreter/bytecode-array-builder.cc |
@@ -450,10 +450,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { |
} |
-BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() { |
+bool BytecodeArrayBuilder::IsAccumulatorBoolean() { |
if (LastBytecodeInSameBlock()) { |
- // If the previous bytecode puts a boolean in the accumulator |
- // there is no need to emit an instruction. |
+ // If the previous bytecode puts a boolean in |
+ // the accumulator return true. |
switch (Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_))) { |
case Bytecode::kToBoolean: |
UNREACHABLE(); |
@@ -470,13 +470,22 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() { |
case Bytecode::kTestGreaterThanOrEqual: |
case Bytecode::kTestInstanceOf: |
case Bytecode::kTestIn: |
- return *this; |
+ return true; |
default: |
- // Fall through to output kToBoolean. |
- break; |
+ return false; |
} |
} |
- Output(Bytecode::kToBoolean); |
+ // If the previous bytecode was from a different block return false. |
+ return false; |
rmcilroy
2015/10/29 10:40:24
nit - do this as an early out at the to, i.e.:
if
mythria
2015/10/29 17:58:39
Done.
|
+} |
+ |
+ |
+BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() { |
+ // If the previous bytecode puts a boolean in the accumulator |
+ // there is no need to emit an instruction. |
+ if (!IsAccumulatorBoolean()) { |
+ Output(Bytecode::kToBoolean); |
+ } |
return *this; |
} |
@@ -573,8 +582,33 @@ void BytecodeArrayBuilder::PatchJump( |
} |
+// static |
+Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode, |
+ bool is_cast_required) { |
+ if (is_cast_required) { |
+ switch (jump_bytecode) { |
+ case Bytecode::kJump: |
+ return Bytecode::kJump; |
+ case Bytecode::kJumpIfTrue: |
+ return Bytecode::kJumpIfToBooleanTrue; |
+ case Bytecode::kJumpIfFalse: |
+ return Bytecode::kJumpIfToBooleanFalse; |
+ default: |
+ UNREACHABLE(); |
+ } |
+ } |
+ return jump_bytecode; |
+} |
+ |
+ |
BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, |
BytecodeLabel* label) { |
+ // Check if the value in accumulator is boolean, if not choose an |
+ // appropriate JumpIfToBoolean bytecode. |
+ bool is_cast_required = !IsAccumulatorBoolean(); |
+ Bytecode jump_boolean_bytecode = |
+ GetJumpWithToBoolean(jump_bytecode, is_cast_required); |
rmcilroy
2015/10/29 10:40:24
Avoid the need for the is_cast_required argument a
mythria
2015/10/29 17:58:39
Done.
|
+ |
int delta; |
if (label->is_bound()) { |
// Label has been bound already so this is a backwards jump. |
@@ -590,11 +624,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, |
} |
if (FitsInImm8Operand(delta)) { |
- Output(jump_bytecode, static_cast<uint8_t>(delta)); |
+ Output(jump_boolean_bytecode, static_cast<uint8_t>(delta)); |
} else { |
size_t entry = GetConstantPoolEntry(handle(Smi::FromInt(delta), isolate())); |
if (FitsInIdx8Operand(entry)) { |
- Output(GetJumpWithConstantOperand(jump_bytecode), |
+ Output(GetJumpWithConstantOperand(jump_boolean_bytecode), |
static_cast<uint8_t>(entry)); |
} else { |
UNIMPLEMENTED(); |
@@ -619,18 +653,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::Throw() { |
Output(Bytecode::kThrow); |
exit_seen_in_block_ = true; |