Пример #1
0
 public override void CompileToDoubleProper(Gen ifProper, Gen ifOther)
 {
     if (IsCacheNeeded)
     {
         // Call CompileToDoubleOrNan via base class CompileToDoubleProper
         base.CompileToDoubleProper(ifProper, ifOther);
     }
     else
     {
         expr.CompileToDoubleProper(ifProper, ifOther);
     }
 }
Пример #2
0
 protected void EvalCondCompile(Action compile)
 {
     if (evalCond != null)
     {
         evalCond.CompileToDoubleProper(
             new Gen(delegate {
             Label endLabel = ilg.DefineLabel();
             ilg.Emit(OpCodes.Ldc_R8, 0.0);
             ilg.Emit(OpCodes.Beq, endLabel);
             compile();
             ilg.MarkLabel(endLabel);
         }),
             new Gen(delegate { }));
     }
     else
     {
         compile();
     }
 }
Пример #3
0
        // Generate code to evaluate all argument expressions, including the receiver es[1]
        // if the method is an instance method, and convert their values to .NET types.

        private void CompileArgumentsAndApply(CGExpr[] es, Gen ifSuccess, Gen ifOther)
        {
            int argCount = es.Length - 1;

            // The error continuations must pop the arguments computed so far:
            Gen[] errorCont = new Gen[argCount];
            if (argCount > 0)
            {
                errorCont[0] = ifOther;
            }
            for (int i = 1; i < argCount; i++)
            {
                int ii = i;                 // Capture lvalue -- do NOT inline!
                errorCont[ii] = new Gen(delegate {
                    ilg.Emit(OpCodes.Pop);
                    errorCont[ii - 1].Generate(ilg);
                });
            }
            // Generate code, backwards, to evaluate argument expressions and
            // convert to external method's argument types
            for (int i = argCount - 1; i >= 0; i--)
            {
                // These local vars capture rvalue rather than lvalue -- do NOT inline them!
                CGExpr ei           = es[i + 1];
                Gen    localSuccess = ifSuccess;
                int    argIndex     = i;
                Type   argType      = ef.ArgType(i);
                Gen    ifError      = errorCont[i];
                // First some special cases to avoid boxing:
                if (argType == typeof(System.Double))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleOrNan();
                        localSuccess.Generate(ilg);
                    });
                }
                else if (argType == typeof(System.Single))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleOrNan();
                        ilg.Emit(OpCodes.Conv_R4);
                        localSuccess.Generate(ilg);
                    });
                }
                else if (signed32.Contains(argType))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleProper(
                            new Gen(delegate {
                            ilg.Emit(OpCodes.Conv_I4);
                            localSuccess.Generate(ilg);
                        }),
                            ifError);
                    });
                }
                else if (unsigned32.Contains(argType))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleProper(
                            new Gen(delegate {
                            ilg.Emit(OpCodes.Conv_U4);
                            localSuccess.Generate(ilg);
                        }),
                            ifError);
                    });
                }
                else if (argType == typeof(System.Int64))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleProper(
                            new Gen(delegate {
                            ilg.Emit(OpCodes.Conv_I8);
                            localSuccess.Generate(ilg);
                        }),
                            ifError);
                    });
                }
                else if (argType == typeof(System.UInt64))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleProper(
                            new Gen(delegate {
                            ilg.Emit(OpCodes.Conv_U8);
                            localSuccess.Generate(ilg);
                        }),
                            ifError);
                    });
                }
                else if (argType == typeof(System.Boolean))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleProper(
                            new Gen(delegate {
                            ilg.Emit(OpCodes.Ldc_R8, 0.0);
                            ilg.Emit(OpCodes.Ceq);
                            localSuccess.Generate(ilg);
                        }),
                            ifError);
                    });
                }
                else if (argType == typeof(System.Char))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.Compile();
                        ilg.Emit(OpCodes.Call, TextValue.toNakedCharMethod);
                        localSuccess.Generate(ilg);
                    });
                }
                else if (argType == typeof(System.String))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.Compile();
                        UnwrapToString(localSuccess, ifError);
                    });
                }
                else                 // General cases: String[], double[], double[,], ...
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.Compile();
                        ilg.Emit(OpCodes.Call, ef.ArgConverter(argIndex).Method);
                        if (argType.IsValueType)                                 // must unbox wrapped value type, but this is too simple-minded
                        {
                            ilg.Emit(OpCodes.Unbox, argType);
                        }
                        localSuccess.Generate(ilg);
                    });
                }
            }
            ifSuccess.Generate(ilg);
        }