コード例 #1
0
ファイル: IfStatement.cs プロジェクト: Bablakeluke/Nitrassic
        /// <summary>
        /// Resolves which function is being called where possible.
        /// </summary>
        internal override void ResolveVariables(OptimizationInfo optimizationInfo)
        {
            // Resolve condition:
            Condition.ResolveVariables(optimizationInfo);

            // Is the condition constant?
            StaticResult = Condition.Evaluate();

            if (StaticResult == null)
            {
                // Resolve both:
                IfClause.ResolveVariables(optimizationInfo);

                if (ElseClause != null)
                {
                    // Only resolve else.
                    ElseClause.ResolveVariables(optimizationInfo);
                }
            }
            else
            {
                // Convert it to a bool:
                bool result = TypeConverter.ToBoolean(StaticResult);

                if (result)
                {
                    // Only resolve if.
                    IfClause.ResolveVariables(optimizationInfo);
                }
                else
                {
                    if (ElseClause != null)
                    {
                        // Only resolve else.
                        ElseClause.ResolveVariables(optimizationInfo);
                    }
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Generates IL for a specific variant of the method. Arguments MUST include 'this' keyword.
        /// </summary>
        public UserDefinedFunction GenerateCode(ArgVariable[] arguments, OptimizationInfo optimizationInfo)
        {
            // Generate the abstract syntax tree if it hasn't already been generated.
            if (this.AbstractSyntaxTree == null)
            {
                Parse(optimizationInfo);

                Dependencies = optimizationInfo.NestedFunctions;
            }

            // Create the param types, which is the args (as they already include 'this'):
            int argCount = arguments == null?0 : arguments.Length;

            Type[] parameters = new Type[argCount];

            for (int i = 0; i < argCount; i++)
            {
                // Transfer the type over:
                parameters[i] = arguments[i].Type;
            }

            string name = GetMethodName();

            // Initialize global code-gen information.
            optimizationInfo.AbstractSyntaxTree      = this.AbstractSyntaxTree;
            optimizationInfo.StrictMode              = this.StrictMode;
            optimizationInfo.MethodOptimizationHints = this.MethodOptimizationHints;
            optimizationInfo.FunctionName            = this.GetStackName();
            optimizationInfo.Source = this.Source;

            ILGenerator generator;

            // Create the UDF now (must be before we generate the code as it would go recursive for recursive functions otherwise):
            UserDefinedFunction mtd = new UserDefinedFunction(name, arguments, this as FunctionMethodGenerator, StrictMode);

            // Add to created set:
            GeneratedMethods.Add(mtd);

            // Clear locals:
            if (InitialScope != null)
            {
                InitialScope.Reset();
            }

            // Resolve variables now:
            AbstractSyntaxTree.ResolveVariables(optimizationInfo);

            // Low trust path.
            ReflectionEmitModuleInfo reflectionEmitInfo = this.Engine.ReflectionEmitInfo;

            var typeBuilder = reflectionEmitInfo.MainType;

            // Create the method builder now:
            var methodBuilder = typeBuilder.DefineMethod(name,
                                                         System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.Static | System.Reflection.MethodAttributes.Public,
                                                         optimizationInfo.ReturnType, parameters);

            mtd.body = methodBuilder;

            // Generate the IL for the method.
            generator = new ReflectionEmitILGenerator(Engine, methodBuilder);

            if (ScriptEngine.EnableILAnalysis)
            {
                // Replace the generator with one that logs.
                generator = new LoggingILGenerator(generator);
            }

            // optimizationInfo.MarkSequencePoint(generator, new SourceCodeSpan(1, 1, 1, 1));
            GenerateCode(arguments, generator, optimizationInfo);
            generator.Complete();

            if (ScriptEngine.EnableILAnalysis)
            {
                // Store the disassembled IL so it can be retrieved for analysis purposes.
                mtd.DisassembledIL = generator.ToString();

                string args = "";

                if (arguments != null)
                {
                    for (int i = 0; i < arguments.Length; i++)
                    {
                        if (i != 0)
                        {
                            args += ",";
                        }
                        args += parameters[i] + " " + arguments[i].Name.ToString();
                    }
                }

                Engine.Log("-IL " + GetMethodName() + "(" + args + ") : " + methodBuilder.ReturnType + "-");
                Engine.Log(mtd.DisassembledIL);
            }

            return(mtd);
        }