/// <summary>
        /// Optimize expressions
        /// </summary>
        public static void Convert(AstBlock ast)
        {
            var variableExpressions = ast.GetExpressions().Where(x => x.Operand is AstVariable).ToList();
            var allVariables        = variableExpressions.Select(x => (AstVariable)x.Operand).Distinct().ToList();
            var allStructVariables  = allVariables.Where(x => x.Type.IsStruct()).ToList();

            var index = 0;

            foreach (var iterator in allStructVariables)
            {
                var variable = iterator;
                if (variable.IsThis || variable.IsParameter)
                {
                    continue;
                }
                if (variableExpressions.Any(x => (x.Operand == variable) && (x.Code == AstCode.Stloc)))
                {
                    continue;
                }

                // Get struct type
                var structType     = variable.Type.Resolve();
                var defaultCtorDef = StructCallConverter.GetDefaultValueCtor(structType);
                var defaultCtor    = variable.Type.CreateReference(defaultCtorDef);

                // Variable is not initialized
                var newObjExpr = new AstExpression(ast.SourceLocation, AstCode.Newobj, defaultCtor).SetType(variable.Type);
                var initExpr   = new AstExpression(ast.SourceLocation, AstCode.Stloc, variable, newObjExpr).SetType(variable.Type);
                ast.Body.Insert(index++, initExpr);
            }
        }
예제 #2
0
        /// <summary>
        /// Perform all dot42 related Ast conversions.
        /// </summary>
        public static void Convert(DecompilerContext context, AstBlock ast, MethodSource currentMethod, AssemblyCompiler compiler)
        {
            if (ast.IsOptimizedForTarget)
            {
                return;
            }
#if DEBUG
            //Debugger.Launch();
            if ((currentMethod.Method != null) && (currentMethod.Method.Name.Equals("runTest", StringComparison.OrdinalIgnoreCase)))
            {
                //Debugger.Launch();
            }
#endif

            IntPtrConverter.Convert(ast, compiler);
            TypeOfConverter.Convert(ast, compiler);
            BranchOptimizer.Convert(ast);
            CompoundAssignmentConverter.Convert(ast);
            ByReferenceParamConverter.Convert(context, ast, compiler);
            CompareUnorderedConverter.Convert(ast);
            EnumConverter.Convert(ast, compiler);
            EnumOptimizer.Convert(ast, compiler);

            // Keep this order
            NullableConverter.Convert(ast, compiler);
            PrimitiveAddressOfConverter.Convert(ast, currentMethod, compiler);
            StructCallConverter.Convert(ast, compiler);
            // end

            InitializeStructVariablesConverter.Convert(ast);
            DelegateConverter.Convert(ast);
            LdcWideConverter.Convert(ast);
            LdLocWithConversionConverter.Convert(ast);
            ConvertAfterLoadConversionConverter.Convert(ast);
            ConvertBeforeStoreConversionConverter.Convert(ast);
            CleanupConverter.Convert(ast);

            GenericsConverter.Convert(ast);

            // Expand cast expressions
            CastConverter.Convert(ast, currentMethod, compiler);

            // Expand generic instance information
            GenericInstanceConverter.Convert(ast, currentMethod, compiler);
        }
예제 #3
0
        private static void ConvertUnboxStruct(AstExpression node, XTypeReference resultType, XTypeSystem typeSystem)
        {
            // Structs must never be null. We have to handle structs here, since a newobj
            // might need generic arguments. These would be difficult to provide at "UnboxFromGeneric",
            // but will be automatically filled in by the GenericInstanceConverter

            // convert to (temp$ = (T)x) != null ? temp$ : default(T)

            // replace any unbox, but keep if otherwise.
            var clone = node.Code == AstCode.Unbox ? new AstExpression(node.Arguments[0]) : new AstExpression(node);

            // make sure we don't evaluate the expression twice.
            var tempVar = new AstGeneratedVariable("temp$", "")
            {
                Type = typeSystem.Object
            };

            // T(x)
            var txExpr = new AstExpression(node.SourceLocation, AstCode.SimpleCastclass, resultType, clone)
                         .SetType(resultType);

            // temporary storage
            var storeTempVar = new AstExpression(node.SourceLocation, AstCode.Stloc, tempVar, txExpr)
            {
                ExpectedType = resultType
            };
            var loadTempVar = new AstExpression(node.SourceLocation, AstCode.Ldloc, tempVar)
                              .SetType(resultType);

            // default (T)
            var defaultT    = new AstExpression(node.SourceLocation, AstCode.DefaultValue, resultType).SetType(resultType);
            var constructor = StructCallConverter.GetDefaultValueCtor(resultType.Resolve());

            StructCallConverter.ConvertDefaultValue(defaultT, constructor);

            // Combine
            var conditional = new AstExpression(node.SourceLocation, AstCode.Conditional, resultType,
                                                storeTempVar, loadTempVar, defaultT)
                              .SetType(resultType);

            node.CopyFrom(conditional);
        }
예제 #4
0
        /// <summary>
        /// Perform all dot42 related Ast conversions.
        /// </summary>
        public static void Convert(DecompilerContext context, AstBlock ast, MethodSource currentMethod, AssemblyCompiler compiler, StopAstConversion stop = StopAstConversion.None)
        {
            if (ast.IsOptimizedForTarget)
            {
                return;
            }
#if DEBUG
            //Debugger.Launch();
            if ((currentMethod.Method != null) && (currentMethod.Method.Name.Equals("runTest", StringComparison.OrdinalIgnoreCase)))
            {
                //Debugger.Launch();
            }
#endif

            IntPtrConverter.Convert(ast, compiler);
            if (stop == StopAstConversion.AfterIntPtrConverter)
            {
                return;
            }

            TypeOfConverter.Convert(ast, compiler);
            if (stop == StopAstConversion.AfterTypeOfConverter)
            {
                return;
            }

            // TODO: check if we actually need this optimizer, as we have a more throughoutful
            //       optimizer as the last step.
            BranchOptimizer.Convert(ast);
            if (stop == StopAstConversion.AfterBranchOptimizer)
            {
                return;
            }

            CompoundAssignmentConverter.Convert(ast);
            if (stop == StopAstConversion.AfterCompoundAssignmentConverter)
            {
                return;
            }

            // keep this order
            FixAsyncStateMachine.Convert(ast, currentMethod, compiler);
            if (stop == StopAstConversion.AfterFixAsyncStateMachine)
            {
                return;
            }

            InterlockedConverter.Convert(ast, currentMethod, compiler);
            if (stop == StopAstConversion.AfterInterlockedConverter)
            {
                return;
            }

            ByReferenceParamConverter.Convert(context, ast, compiler);
            if (stop == StopAstConversion.AfterByReferenceParamConverter)
            {
                return;
            }

            // end
            CompareUnorderedConverter.Convert(ast);
            if (stop == StopAstConversion.AfterCompareUnorderedConverter)
            {
                return;
            }

            EnumConverter.Convert(ast, compiler);
            if (stop == StopAstConversion.AfterEnumConverter)
            {
                return;
            }

            EnumOptimizer.Convert(ast, compiler);
            if (stop == StopAstConversion.AfterEnumOptimizer)
            {
                return;
            }

            // Keep this order
            NullableConverter.Convert(ast, compiler);
            if (stop == StopAstConversion.AfterNullableConverter)
            {
                return;
            }

            PrimitiveAddressOfConverter.Convert(ast, currentMethod, compiler);
            if (stop == StopAstConversion.AfterPrimitiveAddressOfConverter)
            {
                return;
            }

            StructCallConverter.Convert(ast, compiler);
            if (stop == StopAstConversion.AfterStructCallConverter)
            {
                return;
            }
            // end


            InitializeStructVariablesConverter.Convert(ast);
            if (stop == StopAstConversion.AfterInitializeStructVariablesConverter)
            {
                return;
            }

            DelegateConverter.Convert(ast);
            if (stop == StopAstConversion.AfterDelegateConverter)
            {
                return;
            }

            LdcWideConverter.Convert(ast);
            if (stop == StopAstConversion.AfterLdcWideConverter)
            {
                return;
            }

            LdLocWithConversionConverter.Convert(ast);
            if (stop == StopAstConversion.AfterLdLocWithConversionConverter)
            {
                return;
            }

            ConvertAfterLoadConversionConverter.Convert(ast);
            if (stop == StopAstConversion.AfterConvertAfterLoadConversionConverter)
            {
                return;
            }

            ConvertBeforeStoreConversionConverter.Convert(ast);
            if (stop == StopAstConversion.AfterConvertBeforeStoreConversionConverter)
            {
                return;
            }

            CleanupConverter.Convert(ast);
            if (stop == StopAstConversion.AfterCleanupConverter)
            {
                return;
            }

            GenericsConverter.Convert(ast, currentMethod, compiler.Module.TypeSystem);
            if (stop == StopAstConversion.AfterGenericsConverter)
            {
                return;
            }

            // Expand cast expressions
            CastConverter.Convert(ast, currentMethod, compiler);
            if (stop == StopAstConversion.AfterCastConverter)
            {
                return;
            }

            // Expand generic instance information
            GenericInstanceConverter.Convert(ast, currentMethod, compiler);
            if (stop == StopAstConversion.AfterGenericInstanceConverter)
            {
                return;
            }

            // run the branch optimizer again. (do we need the first invocation?)
            BranchOptimizer2.Convert(ast, compiler);
            if (stop == StopAstConversion.AfterBranchOptimizer2)
            {
                return;
            }
        }