Exemple #1
0
        public void AddMethod(MessageContext ctxt, CST.MethodDef methodDef)
        {
            var trace = Parent.Parent;
            var name  = methodDef.QualifiedMemberName(trace.Parent.Env.Global, Parent.Assembly, Type);

            if (trace.Parent.FirstOccuranceOfMethod(ctxt, name, trace))
            {
                Methods.Add(methodDef.MethodSignature);
            }
        }
Exemple #2
0
        private void Collect(CST.Global global, CST.MethodDef methodDef)
        {
            var instructions = methodDef.Instructions(global);

            if (instructions != null)
            {
                foreach (var inst in instructions.Body)
                {
                    if (inst.Flavor == CST.InstructionFlavor.LdString)
                    {
                        var ldstri = (CST.LdStringInstruction)inst;
                        Seen(ldstri.Value);
                    }
                }
            }
        }
Exemple #3
0
        public bool CouldBeInlinableBasedOnHeaderAlone(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
        {
            if (methodDef.IsVirtualOrAbstract || typeDef.Style is CST.InterfaceTypeStyle)
            {
                // No virtuals or interface methods
                return(false);
            }

            if (typeDef.Style is CST.MultiDimArrayTypeStyle)
            {
                // Implemented by runtime
                return(false);
            }

            if (typeDef.IsAttributeType(env.Global, assemblyDef))
            {
                // Don't inline attribute property methods since we invoke them directly when building attributes
                return(false);
            }

            var level = default(ReflectionLevel);

            env.AttributeHelper.GetValueFromType
                (assemblyDef,
                typeDef,
                env.AttributeHelper.ReflectionAttributeRef,
                env.AttributeHelper.TheReflectionLevelProperty,
                true,
                true,
                ref level);
            if (level >= ReflectionLevel.Full)
            {
                // No inlining in classes needing full reflection since need to support dynamic invokes
                return(false);
            }

            // NOTE: Method may be used in a delegate, in which case it's fine to inline but we'll still
            //       need to emit the definition

            if (assemblyDef.EntryPoint != null &&
                assemblyDef.EntryPoint.QualifiedMemberName.Equals
                    (methodDef.QualifiedMemberName(env.Global, assemblyDef, typeDef)))
            {
                // Entry points are called directly by startup code
                return(false);
            }

            return(true);
        }
Exemple #4
0
        public void AddMethod(MessageContext ctxt, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
        {
            var assemblyTrace = ResolveAssemblyTrace(assemblyDef);

            assemblyTrace.AddMethod(ctxt, typeDef, methodDef);
        }
Exemple #5
0
        public void AddMethod(MessageContext ctxt, CST.TypeDef typeDef, CST.MethodDef methodDef)
        {
            var typeTrace = ResolveTypeTrace(typeDef);

            typeTrace.AddMethod(ctxt, methodDef);
        }
Exemple #6
0
 public string ResolveMethodDefToSlot(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
 {
     return(TypeMappingFor(assemblyDef, typeDef).ResolveMethodToSlot
                (methodDef.QualifiedMemberName(env.Global, assemblyDef, typeDef)));
 }
        public ControlFlowRecovery(MethodEnvironment methEnv, Func<JST.Identifier> gensym, int nextInstructionId, CSTWriter tracer)
        {
            this.methEnv = methEnv;
            method = methEnv.Method;
            this.gensym = gensym;
            this.tracer = tracer;

            targets = new Set<int>();
            nextBlockId = 0;
            NextInstructionId = nextInstructionId;
        }
Exemple #8
0
 public abstract bool MethodAlwaysUsed(AssemblyDef assemblyDef, TypeDef typeDef, MethodDef methodDef);
Exemple #9
0
 public abstract bool IgnoreMethodDefBody(AssemblyDef assemblyDef, TypeDef typeDef, MethodDef methodDef);
Exemple #10
0
        public override CST.InvalidInfo ImplementableInstruction(MessageContext ctxt, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef, CST.Instruction instruction)
        {
            switch (instruction.Flavor)
            {
            case CST.InstructionFlavor.Try:
            {
                var tryi = (CST.TryInstruction)instruction;
                if (tryi.Handlers.Any(h => h.Flavor == CST.HandlerFlavor.Filter))
                {
                    Log
                        (new CST.InvalidInstruction
                            (ctxt, instruction, "Exception filter blocks are not supported"));
                    return(new CST.InvalidInfo(CST.MessageContextBuilders.Instruction(Global, instruction)));
                }
                break;
            }

            default:
                break;
            }
            return(null);
        }
Exemple #11
0
 public abstract bool IsAlternateEntryPoint(AssemblyDef assemblyDef, TypeDef typeDef, MethodDef methodDef);
Exemple #12
0
 public override bool IgnoreMethodDefBody(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
 {
     return(env.AttributeHelper.MethodHasAttribute(assemblyDef, typeDef, methodDef, env.AttributeHelper.InteropGeneratedAttributeRef, false, false));
 }
Exemple #13
0
 // NOTE: May be called on invalid definitions
 public override bool IsAlternateEntryPoint(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
 {
     return(env.AttributeHelper.MethodHasAttribute
                (assemblyDef, typeDef, methodDef, env.AttributeHelper.EntryPointAttributeRef, false, false));
 }
Exemple #14
0
        // NOTE: May be called on invalid definitions
        public override bool MethodAlwaysUsed(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
        {
            if (typeDef.Style is CST.DelegateTypeStyle)
            {
                // All the magic delegate methods are inlined by the compiler
                return(false);
            }

#if false
            if (env.AttributeHelper.MethodHasAttribute(assemblyDef, typeDef, methodDef, env.Global.CompilerGeneratedAttributeRef, false))
            {
                return(false);
            }
#endif

            if (env.AttributeHelper.MethodHasAttribute
                    (assemblyDef, typeDef, methodDef, env.AttributeHelper.IgnoreAttributeRef, true, true))
            {
                return(false);
            }

            if (typeDef.IsModule && methodDef.IsStatic && methodDef.IsConstructor)
            {
                return(true);
            }

            if (HasFullReflection(assemblyDef, typeDef))
            {
                return(true);
            }

            var isUsed = default(bool);
            env.AttributeHelper.GetValueFromMethod
                (assemblyDef,
                typeDef,
                methodDef,
                env.AttributeHelper.UsedAttributeRef,
                env.AttributeHelper.TheIsUsedProperty,
                true,
                false,
                ref isUsed);
            if (isUsed)
            {
                return(true);
            }

            if (env.InteropManager.IsExported(assemblyDef, typeDef, methodDef))
            {
                // Exported methods always used
                return(true);
            }

            return(false);
        }
Exemple #15
0
        public bool IsInlinable(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
        {
            var s = MethodBodySize(methodDef.QualifiedMemberName(env.Global, assemblyDef, typeDef));

            return(s >= 0 && s <= env.InlineThreshold);
        }
Exemple #16
0
 public abstract InvalidInfo ImplementableInstruction(MessageContext ctxt, AssemblyDef assemblyDef, TypeDef typeDef, MethodDef methodDef, Instruction instruction);
Exemple #17
0
        // See also: InteropManager::IsInlinable
        private bool PrimIsInlinable(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
        {
            if (!CouldBeInlinableBasedOnHeaderAlone(assemblyDef, typeDef, methodDef))
            {
                return(false);
            }

            if (methodDef.IsRecursive)
            {
                // No recursive methods
                return(false);
            }

            if (methodDef.IsConstructor)
            {
                // No instance constructors (since we can't enline NewExpressions yet), and
                // no static constructors (since we can't inline calls emitted in assembly Initialize)
                return(false);
            }

            if (env.InteropManager.IsImported(assemblyDef, typeDef, methodDef) ||
                env.InteropManager.IsExported(assemblyDef, typeDef, methodDef))
            {
                // No imported methods (we inline separately), and
                // no exported methods (we need the definition around to be able to export it)
                return(false);
            }

            if (methodDef.MethodBody == null || methodDef.MethodBody.Instructions.Length == 0)
            {
                // No empty methods or imported methods
                return(false);
            }

            var numReturns   = 0;
            var instructions = methodDef.Instructions(env.Global);

            if (!instructions.IsInlinable(ref numReturns) || numReturns != 1)
            {
                // Non-inlinable instructions
                return(false);
            }

            var code = instructions.Body[instructions.Body.Count - 1].Code;

            if (code != CST.InstructionCode.Ret && code != CST.InstructionCode.RetVal)
            {
                // Last instruction is not return
                return(false);
            }

            // NOTE: Even though instructions have a single return, it is still possible the translated statatements
            //       won't have a unique result, so unfortunately we need to check that below

            var isInline       = default(bool);
            var overrideInline = env.AttributeHelper.GetValueFromMethod
                                     (assemblyDef,
                                     typeDef,
                                     methodDef,
                                     env.AttributeHelper.InlineAttributeRef,
                                     env.AttributeHelper.TheIsInlinedProperty,
                                     true,
                                     false,
                                     ref isInline);

            if (overrideInline && !isInline)
            {
                // User has supressed inlining
                return(false);
            }

            if (!overrideInline && instructions.Size > env.InlineThreshold)
            {
                // Method too large
                return(false);
            }

            var methEnv =
                env.Global.Environment().AddAssembly(assemblyDef).AddType(typeDef).AddSelfTypeBoundArguments().
                AddMethod(methodDef).AddSelfMethodBoundArguments();
            var cstmethod = CST.CSTMethod.Translate(methEnv, new JST.NameSupply(), null);
            var body      = new Seq <CST.Statement>();
            var retres    = cstmethod.Body.ToReturnResult(body);

            if (retres.Status != CST.ReturnStatus.One)
            {
                // More than one return
                return(false);
            }

            return(true);
        }
 public MachineStateInference(MethodEnvironment methEnv, CSTWriter tracer)
 {
     this.methEnv = methEnv;
     global = methEnv.Global;
     method = methEnv.Method;
     this.tracer = tracer;
     offsetToBeforeState = new Map<int, MachineState>();
     offsetToAfterState = new Map<int, MachineState>();
 }