// Generates optimized OrElse with branch == true // or optimized AndAlso with branch == false private void EmitBranchOr(bool branch, BinaryExpression node, Label label) { // if (left OR right) branch label if (ConstantCheck.IsConstant(node.Left, branch)) { _ilg.Emit(OpCodes.Br, label); } else { if (!ConstantCheck.IsConstant(node.Left, !branch)) { EmitExpressionAndBranch(branch, node.Left, label); } if (ConstantCheck.IsConstant(node.Right, branch)) { _ilg.Emit(OpCodes.Br, label); } else if (!ConstantCheck.IsConstant(node.Right, !branch)) { EmitExpressionAndBranch(branch, node.Right, label); } } }
// Generates optimized AndAlso with branch == true // or optimized OrElse with branch == false private void EmitBranchAnd(bool branch, BinaryExpression node, Label label) { // if (left AND right) branch label if (!ConstantCheck.IsConstant(node.Left, !branch) && !ConstantCheck.IsConstant(node.Right, !branch)) { if (ConstantCheck.IsConstant(node.Left, branch)) { EmitExpressionAndBranch(branch, node.Right, label); } else if (ConstantCheck.IsConstant(node.Right, branch)) { EmitExpressionAndBranch(branch, node.Left, label); } else { // if (left) then // if (right) branch label // endif Label endif = _ilg.DefineLabel(); EmitExpressionAndBranch(!branch, node.Left, endif); EmitExpressionAndBranch(branch, node.Right, label); _ilg.MarkLabel(endif); } } }