Chromium Code Reviews| Index: src/interpreter/bytecode-generator.cc |
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc |
| index 423c438cf2c17910227d08fd4b873294538d2dbb..708109251c7788201b01bbe5608ba4cd833296ab 100644 |
| --- a/src/interpreter/bytecode-generator.cc |
| +++ b/src/interpreter/bytecode-generator.cc |
| @@ -777,9 +777,13 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { |
| void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) { |
| switch (binop->op()) { |
| case Token::COMMA: |
| + VisitCommaExpression(binop); |
| + break; |
| case Token::OR: |
| + VisitLogicalOrExpression(binop); |
| + break; |
| case Token::AND: |
| - UNIMPLEMENTED(); |
| + VisitLogicalAndExpression(binop); |
| break; |
| default: |
| VisitArithmeticExpression(binop); |
| @@ -842,6 +846,73 @@ void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* binop) { |
| } |
| +void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) { |
| + Expression* left = binop->left(); |
| + Expression* right = binop->right(); |
| + |
| + TemporaryRegisterScope temporary_register_scope(&builder_); |
| + Register temporary = temporary_register_scope.NewRegister(); |
| + |
| + Visit(left); |
| + builder()->StoreAccumulatorInRegister(temporary); |
| + Visit(right); |
| +} |
| + |
| + |
| +void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) { |
| + Expression* left = binop->left(); |
| + Expression* right = binop->right(); |
| + |
| + TemporaryRegisterScope temporary_register_scope(&builder_); |
| + Register temporary = temporary_register_scope.NewRegister(); |
| + |
| + // Short-circuit evaluation- If it is known that left is always true, |
| + // no need to visit right |
| + if (left->ToBooleanIsTrue()) { |
| + Visit(left); |
| + } else { |
| + BytecodeLabel else_label, end_label; |
| + |
| + Visit(left); |
| + builder()->StoreAccumulatorInRegister(temporary); |
| + builder()->CastAccumulatorToBoolean(); |
| + builder()->JumpIfFalse(&else_label); |
| + builder()->LoadAccumulatorWithRegister(temporary); |
| + builder()->Jump(&end_label); |
| + builder()->Bind(&else_label); |
|
rmcilroy
2015/10/12 07:24:13
I think we should add a pair of bytecodes which pe
mythria
2015/10/13 15:00:00
Done.
|
| + Visit(right); |
| + builder()->Bind(&end_label); |
| + } |
| +} |
| + |
| + |
| +void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) { |
| + Expression* left = binop->left(); |
| + Expression* right = binop->right(); |
| + |
| + TemporaryRegisterScope temporary_register_scope(&builder_); |
| + Register temporary = temporary_register_scope.NewRegister(); |
| + |
| + // Short-circuit evaluation- If it is known that left is always false, |
| + // no need to visit right |
| + if (left->ToBooleanIsFalse()) { |
| + Visit(left); |
| + } else { |
| + BytecodeLabel else_label, end_label; |
| + |
| + Visit(left); |
| + builder()->StoreAccumulatorInRegister(temporary); |
| + builder()->CastAccumulatorToBoolean(); |
| + builder()->JumpIfTrue(&else_label); |
| + builder()->LoadAccumulatorWithRegister(temporary); |
| + builder()->Jump(&end_label); |
| + builder()->Bind(&else_label); |
| + Visit(right); |
| + builder()->Bind(&end_label); |
| + } |
| +} |
| + |
| + |
| LanguageMode BytecodeGenerator::language_mode() const { |
| return info()->language_mode(); |
| } |