Ancestry.QueryProcessor.Type.BaseType.EmitShortCircuit C# (CSharp) Method

EmitShortCircuit() protected method

Overridden to determine what operators a type supports and to change how they are implemented.
Override this rather than CompileBinaryOperator when nothing special is necessary when compiling the right-hand expression.
protected EmitShortCircuit ( MethodContext method, Compiler compiler, Frame frame, ExpressionContext left, ExpressionContext right, Parse expression, Type typeHint ) : void
method Ancestry.QueryProcessor.Compile.MethodContext
compiler Compiler
frame Frame
left Ancestry.QueryProcessor.Compile.ExpressionContext
right Ancestry.QueryProcessor.Compile.ExpressionContext
expression Parse
typeHint System.Type
return void
        protected virtual void EmitShortCircuit(MethodContext method, Compiler compiler, Frame frame, ExpressionContext left, ExpressionContext right, Parse.BinaryExpression expression, Type.BaseType typeHint)
        {
            var leftType = left.Type.GetNative(compiler.Emitter);
            var rightType = right.Type.GetNative(compiler.Emitter);
            left.EmitGet(method);
            right.EmitGet(method);
            switch (expression.Operator)
            {
                case Parse.Operator.And:
                    if (!CallClassOp(method, "op_LogicalAnd", leftType, leftType))
                    {
                        var label = method.IL.DefineLabel();
                        method.IL.Emit(OpCodes.Dup);
                        method.IL.Emit(OpCodes.Brfalse_S, label);
                        right.EmitGet(method);
                        method.IL.Emit(OpCodes.And);
                        method.IL.MarkLabel(label);
                    }
                    break;

                case Parse.Operator.Or:
                    if (!CallClassOp(method, "op_LogicalOr", leftType, leftType))
                    {
                        var label = method.IL.DefineLabel();
                        method.IL.Emit(OpCodes.Dup);
                        method.IL.Emit(OpCodes.Brtrue_S, label);
                        right.EmitGet(method);
                        method.IL.Emit(OpCodes.Or);
                        method.IL.MarkLabel(label);
                    }
                    break;

                default: throw new NotSupportedException(String.Format("Operator {0} is not supported.", expression.Operator));
            }
        }