Exemplo n.º 1
0
        public override bool PropogateExtraUsedFromMember(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MemberDef memberDef)
        {
            var newUsed = false;

            var methodDef = memberDef as CST.MethodDef;

            if (methodDef != null)
            {
                if (!methodDef.IsStatic && methodDef.IsConstructor &&
                    env.InteropManager.IsImported(assemblyDef, typeDef, methodDef) &&
                    !env.InteropManager.IsFactory(assemblyDef, typeDef, methodDef))
                {
                    // Imported instance constructor may invoke an 'importing' constructor
                    var polyMethEnv =
                        Global.Environment().AddAssembly(assemblyDef).AddType(typeDef).AddSelfTypeBoundArguments().
                        AddMethod(methodDef);
                    var methodRef = env.InteropManager.BestImportingConstructor(polyMethEnv);
                    if (methodRef != null)
                    {
                        if (ExtraUsedMethod(methodRef.QualifiedMemberName))
                        {
                            newUsed = true;
                        }
                    }
                }
            }

            return(newUsed);
        }
Exemplo n.º 2
0
 public void Collect(CST.Global global, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
 {
     foreach (var methodDef in typeDef.Members.OfType <CST.MethodDef>().Where(m => m.IsUsed && m.Invalid == null))
     {
         Collect(global, methodDef);
     }
 }
Exemplo n.º 3
0
 public AssemblyTrace(Trace parent, CST.AssemblyDef assembly)
 {
     Parent          = parent;
     Assembly        = assembly;
     IncludeAssembly = false;
     TypeMap         = new Map <CST.TypeName, TypeTrace>();
 }
Exemplo n.º 4
0
        public override bool PropogateExtraUsedFromType(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
        {
            var newUsed = false;

            var state = env.InteropManager.GetTypeRepresentation(assemblyDef, typeDef).State;

            if (state == InstanceState.JavaScriptOnly || state == InstanceState.ManagedAndJavaScript)
            {
                var typeEnv =
                    Global.Environment().AddAssembly(assemblyDef).AddType(typeDef).AddSelfTypeBoundArguments();
                var methodRef = env.InteropManager.DefaultImportingConstructor(typeEnv);
                if (methodRef != null)
                {
                    // Default importing constructor is used if its type is used
                    if (ExtraUsedMethod(methodRef.QualifiedMemberName))
                    {
                        newUsed = true;
                    }
                }
            }



            return(newUsed);
        }
Exemplo n.º 5
0
        public TypeMapping(CompilerEnvironment env, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
        {
            ctxt             = CST.MessageContextBuilders.Type(env.Global, assemblyDef, typeDef);
            this.env         = env;
            this.assemblyDef = assemblyDef;
            this.typeDef     = typeDef;

            // Method slots appear as field names in type structures and directory names on disk.
            // Thus we use lower-case identifiers.
            methodSlots = new SlotAllocation <CST.QualifiedMemberName>
                              (env.DebugMode, NameFlavor.LowercaseIdentifier, FriendlyMemberName);

            // Field slots appear in object annd type structuers, but always prefixed by 'S' or 'F'.
            // Thus we use arbitrary identifiers.
            fieldSlots = new SlotAllocation <CST.QualifiedMemberName>
                             (env.DebugMode, NameFlavor.Identifier, FriendlyMemberName);

            // Similarly for event slots, but prefixed by 'E'.
            eventSlots = new SlotAllocation <CST.QualifiedMemberName>
                             (env.DebugMode, NameFlavor.Identifier, FriendlyMemberName);

            // Similarly for property slots (needed only by reflection), but prefixed by 'R'
            propSlots = new SlotAllocation <CST.QualifiedMemberName>
                            (env.DebugMode, NameFlavor.Identifier, FriendlyMemberName);

            AddNames(env, assemblyDef, typeDef, methodSlots, fieldSlots, eventSlots, propSlots);

            // Defer till ask for string slot
            stringSlots = null;
        }
Exemplo n.º 6
0
 public AssemblyTrace(Trace parent, CST.AssemblyDef assembly)
 {
     Parent = parent;
     Assembly = assembly;
     IncludeAssembly = false;
     TypeMap = new Map<CST.TypeName, TypeTrace>();
 }
Exemplo n.º 7
0
        // NOTE: May be called on invalid definitions
        public override bool FieldAlwaysUsed(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.FieldDef fieldDef)
        {
#if false
            if (env.AttributeHelper.FieldHasAttribute(assemblyDef, typeDef, fieldDef, env.Global.CompilerGeneratedAttributeRef, false))
            {
                return(false);
            }
#endif
            if (env.AttributeHelper.FieldHasAttribute(assemblyDef, typeDef, fieldDef, env.AttributeHelper.IgnoreAttributeRef, true, true))
            {
                return(false);
            }

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

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

            return(false);
        }
Exemplo n.º 8
0
        public AssemblyMapping(CompilerEnvironment env, CST.AssemblyDef assemblyDef)
        {
            ctxt = CST.MessageContextBuilders.Assembly(env.Global, assemblyDef);

            // Type slots appear as field names in assembly structure, possibly without prefixes, and
            // as directory names on disk
            types = new SlotAllocation <CST.TypeName>(env.DebugMode, NameFlavor.LowercaseIdentifier, FriendlyTypeName);

            if (assemblyDef.Name.Equals(env.Global.MsCorLibName))
            {
                types.Add(env.Global.ArrayTypeConstructorRef.QualifiedTypeName.Type);
                types.Add(env.Global.ManagedPointerTypeConstructorRef.QualifiedTypeName.Type);
            }

            // Types are already in canonical order
            foreach (var typeDef in assemblyDef.Types.Where(t => t.IsUsed && t.Invalid == null))
            {
                types.Add(typeDef.EffectiveName(env.Global));
            }

            // Assembly slots appear as field names in assembly structures, prefixed by 'A'
            referencedAssemblies = new SlotAllocation <CST.AssemblyName>
                                       (env.DebugMode, NameFlavor.Identifier, FriendlyAssemblyName);

            var assmEnv = env.Global.Environment().AddAssembly(assemblyDef);

            foreach (var nm in assmEnv.AllAssembliesInLoadOrder())
            {
                if (!nm.Equals(env.Global.MsCorLibName) && !nm.Equals(assemblyDef.Name))
                {
                    referencedAssemblies.Add(nm);
                }
                // else: mscorlib is bound into root structure, don't need self ref
            }
        }
Exemplo n.º 9
0
 // Collecting mode entry point
 public AssemblyCompiler(CompilerEnvironment env, CST.AssemblyDef assemblyDef)
     : this(env)
 {
     assmEnv       = env.Global.Environment().AddAssembly(assemblyDef);
     assemblyTrace = null;
     NameSupply    = new JST.NameSupply(Constants.Globals);
     rootId        = NameSupply.GenSym();
     assemblyId    = NameSupply.GenSym();
 }
Exemplo n.º 10
0
 public override void ImplementableTypeDef(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
 {
     if (env.AttributeHelper.TypeHasAttribute
             (assemblyDef, typeDef, env.AttributeHelper.IgnoreAttributeRef, true, true))
     {
         var ctxt = CST.MessageContextBuilders.Type(env.Global, assemblyDef, typeDef);
         Log(new CST.InvalidTypeDef(ctxt, "Type is marked as '[Ignore]'"));
         typeDef.Invalid = new CST.InvalidInfo("Ignored");
     }
 }
Exemplo n.º 11
0
        private AssemblyTrace ResolveAssemblyTrace(CST.AssemblyDef assemblyDef)
        {
            var assemblyTrace = default(AssemblyTrace);

            if (!AssemblyMap.TryGetValue(assemblyDef.Name, out assemblyTrace))
            {
                assemblyTrace = new AssemblyTrace(this, assemblyDef);
                AssemblyMap.Add(assemblyDef.Name, assemblyTrace);
            }
            return(assemblyTrace);
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
0
        private TypeMapping TypeMappingFor(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
        {
            var name        = typeDef.QualifiedTypeName(env.Global, assemblyDef);
            var typeMapping = default(TypeMapping);

            if (!typeMappingCache.TryGetValue(name, out typeMapping))
            {
                typeMapping = new TypeMapping(env, assemblyDef, typeDef);
                typeMappingCache.Add(name, typeMapping);
            }
            return(typeMapping);
        }
Exemplo n.º 14
0
        private AssemblyMapping AssemblyMappingFor(CST.AssemblyDef assemblyDef)
        {
            var name            = assemblyDef.Name;
            var assemblyMapping = default(AssemblyMapping);

            if (!assemblyMappingCache.TryGetValue(name, out assemblyMapping))
            {
                assemblyMapping = new AssemblyMapping(env, assemblyDef);
                assemblyMappingCache.Add(name, assemblyMapping);
            }
            return(assemblyMapping);
        }
Exemplo n.º 15
0
        private bool HasFullReflection(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
        {
            var level = default(ReflectionLevel);

            env.AttributeHelper.GetValueFromType
                (assemblyDef,
                typeDef,
                env.AttributeHelper.ReflectionAttributeRef,
                env.AttributeHelper.TheReflectionLevelProperty,
                true,
                true,
                ref level);
            return(level >= ReflectionLevel.Full);
        }
Exemplo n.º 16
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);
        }
Exemplo n.º 17
0
        private static bool IsUpToDate(CompilerEnvironment env, CST.AssemblyDef assembly, bool complain)
        {
            var annot = assembly.Annotations.OfType <CST.AssemblyFileAnnotation>().FirstOrDefault();

            if (annot == null)
            {
                throw new InvalidOperationException("assembly is missing file annotation");
            }
            var fn           = default(string);
            var lastCompTime = AssemblyCompiler.LastCompilationTime(env, assembly.Name, out fn);

            if (lastCompTime.HasValue)
            {
                if (annot.LastWriteTime <= lastCompTime.Value)
                {
                    return(true);
                }
                else
                {
                    if (complain)
                    {
                        env.Log
                            (new OutOfDateAssemblyMessage(assembly.Name, annot.CanonicalFileName, fn));
                    }
                    return(false);
                }
            }
            else
            {
                if (complain)
                {
                    env.Log(new AssemblyNotCompiledMessage(assembly.Name, fn));
                }
                return(false);
            }
        }
Exemplo n.º 18
0
 internal override void AccumUsedTypeAndMemberDefs(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef)
 {
     base.AccumUsedTypeAndMemberDefs(vctxt, assemblyDef, typeDef);
     var ctxt = MessageContextBuilders.Member(vctxt.Global, assemblyDef, typeDef, this);
     if (Get != null)
     {
         Invalid = Get.AccumUsedTypeDefs(vctxt, ctxt, usedTypes);
         if (Invalid != null)
             return;
     }
     if (Set != null)
     {
         Invalid = Set.AccumUsedTypeDefs(vctxt, ctxt, usedTypes);
         if (Invalid != null)
             return;
     }
     Invalid = FieldType.AccumUsedTypeDefs(vctxt, ctxt, usedTypes);
 }
Exemplo n.º 19
0
        internal void TopologicalAllDeps(Global global, AssemblyDef assemblyDef, TypeDef typeDef, Set<QualifiedMemberName> visitedMemberDefs, Seq<QualifiedMemberName> sortedMemberDefs)
        {
            var self = QualifiedMemberName(global, assemblyDef, typeDef);
            if (visitedMemberDefs.Contains(self))
                return;
            visitedMemberDefs.Add(self);

            if (usedTypes == null)
                return;

            foreach (var r in usedTypes)
            {
                var usedAssemblyDef = default(AssemblyDef);
                var usedTypeDef = default(TypeDef);
                if (r.PrimTryResolve(global, out usedAssemblyDef, out usedTypeDef))
                    usedTypeDef.UsedBy(self);
            }

            foreach (var r in usedMembers)
            {
                var usedAssemblyDef = default(AssemblyDef);
                var usedTypeDef = default(TypeDef);
                var usedMemberDef = default(MemberDef);
                if (r.PrimTryResolve(global, out usedAssemblyDef, out usedTypeDef, out usedMemberDef))
                {
                    usedMemberDef.UsedBy(self);
                    usedMemberDef.TopologicalAllDeps
                        (global, usedAssemblyDef, usedTypeDef, visitedMemberDefs, sortedMemberDefs);
                }
            }

            sortedMemberDefs.Add(self);
        }
Exemplo n.º 20
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);
        }
Exemplo n.º 21
0
 internal virtual void AccumUsedTypeAndMemberDefs(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef)
 {
     usedTypes = new Set<QualifiedTypeName>();
     usedMembers = new Set<QualifiedMemberName>();
 }
Exemplo n.º 22
0
 internal override void AccumUsedTypeAndMemberDefs(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef)
 {
     base.AccumUsedTypeAndMemberDefs(vctxt, assemblyDef, typeDef);
     var ctxt = MessageContextBuilders.Member(vctxt.Global, assemblyDef, typeDef, this);
     Invalid = FieldType.AccumUsedTypeDefs(vctxt, ctxt, usedTypes);
 }
Exemplo n.º 23
0
        public override void ImplementableMemberDef(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MemberDef memberDef)
        {
            var ctxt = CST.MessageContextBuilders.Member(env.Global, assemblyDef, typeDef, memberDef);
            var s    = typeDef.Style;

            var methodDef = memberDef as CST.MethodDef;

            if (methodDef == null)
            {
                return;
            }

            if (s is CST.DelegateTypeStyle || s is CST.MultiDimArrayTypeStyle)
            {
                // SPECIAL CASE: Magic delegate and multi-dimensional array methods are
                //               implemented by runtime
                return;
            }

            if (env.AttributeHelper.MethodHasAttribute
                    (assemblyDef, typeDef, methodDef, env.AttributeHelper.IgnoreAttributeRef, true, true))
            {
                Log(new CST.InvalidMemberDef(ctxt, "Method is marked as '[Ignore]'"));
                methodDef.Invalid = new CST.InvalidInfo("Ignored");
            }

            try
            {
                if (!(s is CST.InterfaceTypeStyle) && methodDef.MethodStyle != CST.MethodStyle.Abstract &&
                    !env.InteropManager.IsImported(assemblyDef, typeDef, methodDef))
                {
                    switch (methodDef.CodeFlavor)
                    {
                    case CST.MethodCodeFlavor.Managed:
                    {
                        var instructions = methodDef.Instructions(Global);
                        if (instructions == null || instructions.Body.Count == 0)
                        {
                            Log(new CST.InvalidMemberDef(ctxt, "Method has no body"));
                            methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
                        }
                        break;
                    }

                    case CST.MethodCodeFlavor.ManagedExtern:
                        Log(new CST.InvalidMemberDef(ctxt, "Method is marked as extern but has no import"));
                        methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
                        break;

                    case CST.MethodCodeFlavor.Native:
                        Log(new CST.InvalidMemberDef(ctxt, "Method invokes native code"));
                        methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
                        break;

                    case CST.MethodCodeFlavor.Runtime:
                        Log(new CST.InvalidMemberDef(ctxt, "Method is part of the CLR runtime"));
                        methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
                        break;

                    case CST.MethodCodeFlavor.ForwardRef:
                        Log(new CST.InvalidMemberDef(ctxt, "Method is a forward reference"));
                        methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
                // else: no body to check
            }
            catch (DefinitionException)
            {
                Log(new CST.InvalidMemberDef(ctxt, "Method contains an interop error"));
                methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
            }
        }
Exemplo n.º 24
0
 public abstract bool PropogateExtraUsedFromType(AssemblyDef assemblyDef, TypeDef typeDef);
Exemplo n.º 25
0
 public MethodRef PrimMethodReference(Global global, AssemblyDef assemblyDef, TypeDef typeDef, IImSeq<TypeRef> typeBoundArguments, IImSeq<TypeRef> methodBoundArguments)
 {
     return new MethodRef
         (typeDef.PrimReference(global, assemblyDef, typeBoundArguments),
          Name,
          IsStatic,
          methodBoundArguments,
          ValueParameters.Select(p => p.Type).ToSeq(),
          Result == null ? null : Result.Type);
 }
Exemplo n.º 26
0
 public abstract bool EventAlwaysUsed(AssemblyDef assemblyDef, TypeDef typeDef, EventDef eventDef);
Exemplo n.º 27
0
 public abstract bool IncludeAttributes(AssemblyDef assemblyDef, TypeDef typeDef);
Exemplo n.º 28
0
 public abstract bool PropertyAlwaysUsed(AssemblyDef assemblyDef, TypeDef typeDef, PropertyDef propDef);
Exemplo n.º 29
0
 public abstract bool FieldAlwaysUsed(AssemblyDef assemblyDef, TypeDef typeDef, FieldDef fieldDef);
Exemplo n.º 30
0
 public abstract bool MethodAlwaysUsed(AssemblyDef assemblyDef, TypeDef typeDef, MethodDef methodDef);
Exemplo n.º 31
0
        internal void PropogateInvalidity(Global global, AssemblyDef assemblyDef, TypeDef typeDef)
        {
            if (Invalid == null)
                return;

            if (usedByMembers != null)
            {
                var self = PrimReference(global, assemblyDef, typeDef, null);
                foreach (var r in usedByMembers)
                {
                    var usedByAssemblyDef = default(AssemblyDef);
                    var usedByTypeDef = default(TypeDef);
                    var usedByMemberDef = default(MemberDef);
                    if (r.PrimTryResolve(global, out usedByAssemblyDef, out usedByTypeDef, out usedByMemberDef))
                    {
                        if (usedByMemberDef.Invalid == null)
                            usedByMemberDef.Invalid = new InvalidInfo(MessageContextBuilders.Member(global, self), Invalid);
                    }
                }
            }
        }
Exemplo n.º 32
0
 public abstract bool PropogateExtraUsedFromMember(AssemblyDef assemblyDef, TypeDef typeDef, MemberDef memberDef);
Exemplo n.º 33
0
 internal virtual void TopologicalTypeInitFromImplementors(Global global, AssemblyDef assemblyDef, TypeDef typeDef, Set<QualifiedTypeName> visitedTypeDefs, Seq<QualifiedTypeName> sortedTypeDefs, Set<QualifiedMemberName> visitedMemberDefs)
 {
 }
Exemplo n.º 34
0
 public abstract bool IgnoreMethodDefBody(AssemblyDef assemblyDef, TypeDef typeDef, MethodDef methodDef);
Exemplo n.º 35
0
 internal override void TopologicalTypeInitFromImplementors(Global global, AssemblyDef assemblyDef, TypeDef typeDef, Set<QualifiedTypeName> visitedTypeDefs, Seq<QualifiedTypeName> sortedTypeDefs, Set<QualifiedMemberName> visitedMemberDefs)
 {
     if (implementors != null)
     {
         foreach (var r in implementors)
         {
             var usedAssemblyDef = default(AssemblyDef);
             var usedTypeDef = default(TypeDef);
             var usedMemberDef = default(MemberDef);
             if (r.PrimTryResolve(global, out usedAssemblyDef, out usedTypeDef, out usedMemberDef))
                 usedMemberDef.TopologicalTypeInit
                     (global, usedAssemblyDef, usedTypeDef, visitedTypeDefs, sortedTypeDefs, visitedMemberDefs);
         }
     }
 }
Exemplo n.º 36
0
 public abstract void ImplementableMemberDef(AssemblyDef assemblyDef, TypeDef typeDef, MemberDef memberDef);
Exemplo n.º 37
0
 public override MemberRef PrimReference(Global global, AssemblyDef assemblyDef, TypeDef typeDef, IImSeq<TypeRef> typeBoundArguments)
 {
     return new EventRef(typeDef.PrimReference(global, assemblyDef, typeBoundArguments), Name);
 }
Exemplo n.º 38
0
 public abstract InvalidInfo ImplementableInstruction(MessageContext ctxt, AssemblyDef assemblyDef, TypeDef typeDef, MethodDef methodDef, Instruction instruction);
Exemplo n.º 39
0
 public string ResolveTypeDefToSlot(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
 {
     return(AssemblyMappingFor(assemblyDef).ResolveTypeDefinitionToSlot(typeDef.EffectiveName(env.Global)));
 }
Exemplo n.º 40
0
        public TypeMapping(CompilerEnvironment env, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
        {
            ctxt = CST.MessageContextBuilders.Type(env.Global, assemblyDef, typeDef);
            this.env = env;
            this.assemblyDef = assemblyDef;
            this.typeDef = typeDef;

            // Method slots appear as field names in type structures and directory names on disk.
            // Thus we use lower-case identifiers.
            methodSlots = new SlotAllocation<CST.QualifiedMemberName>
                (env.DebugMode, NameFlavor.LowercaseIdentifier, FriendlyMemberName);

            // Field slots appear in object annd type structuers, but always prefixed by 'S' or 'F'.
            // Thus we use arbitrary identifiers.
            fieldSlots = new SlotAllocation<CST.QualifiedMemberName>
                (env.DebugMode, NameFlavor.Identifier, FriendlyMemberName);

            // Similarly for event slots, but prefixed by 'E'.
            eventSlots = new SlotAllocation<CST.QualifiedMemberName>
                (env.DebugMode, NameFlavor.Identifier, FriendlyMemberName);

            // Similarly for property slots (needed only by reflection), but prefixed by 'R'
            propSlots = new SlotAllocation<CST.QualifiedMemberName>
                (env.DebugMode, NameFlavor.Identifier, FriendlyMemberName);

            AddNames(env, assemblyDef, typeDef, methodSlots, fieldSlots, eventSlots, propSlots);

            // Defer till ask for string slot
            stringSlots = null;
        }
Exemplo n.º 41
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);
        }
Exemplo n.º 42
0
        private static void AddNames(
            CompilerEnvironment env,
            CST.AssemblyDef assemblyDef,
            CST.TypeDef typeDef,
            SlotAllocation <CST.QualifiedMemberName> methodSlots,
            SlotAllocation <CST.QualifiedMemberName> fieldSlots,
            SlotAllocation <CST.QualifiedMemberName> eventSlots,
            SlotAllocation <CST.QualifiedMemberName> propSlots)
        {
            // Allocate slots for any base type so that this type's slots won't collide with them.
            // NOTE: Not strictly necessary for methods, since only virtual methods of supertype may find their
            //       way into derived type, but seems easiest to just allocate them all.
            // NOTE: Interface method slots need only be unique within their interface type since the type
            //       id is included in the final slot name.
            if (typeDef.Extends != null)
            {
                var extAssemblyDef = default(CST.AssemblyDef);
                var extTypeDef     = default(CST.TypeDef);
                if (typeDef.Extends.PrimTryResolve(env.Global, out extAssemblyDef, out extTypeDef))
                {
                    AddNames(env, extAssemblyDef, extTypeDef, methodSlots, fieldSlots, eventSlots, propSlots);
                }
            }

            // Members are already in canonical order
            foreach (var memberDef in typeDef.Members.Where(m => m.IsUsed && m.Invalid == null))
            {
                var name = memberDef.QualifiedMemberName(env.Global, assemblyDef, typeDef);
                switch (memberDef.Flavor)
                {
                case CST.MemberDefFlavor.Field:
                {
                    fieldSlots.Add(name);
                    break;
                }

                case CST.MemberDefFlavor.Event:
                {
                    eventSlots.Add(name);
                    break;
                }

                case CST.MemberDefFlavor.Method:
                {
                    methodSlots.Add(name);
                    break;
                }

                case CST.MemberDefFlavor.Property:
                {
                    propSlots.Add(name);
                    break;
                }

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return;
        }
Exemplo n.º 43
0
 public override MemberRef PrimReference(Global global, AssemblyDef assemblyDef, TypeDef typeDef, IImSeq<TypeRef> typeBoundArguments)
 {
     var sig = PropertySignature;
     return new PropertyRef
         (typeDef.PrimReference(global, assemblyDef, typeBoundArguments),
          sig.Name,
          sig.IsStatic,
          sig.Parameters,
          sig.Result);
 }
Exemplo n.º 44
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));
 }
Exemplo n.º 45
0
        internal bool MarkAsUsed(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef)
        {
            if (IsUsed || Invalid != null || typeDef.Invalid != null)
                return false;
            IsUsed = true;

            typeDef.MarkAsUsed(vctxt, assemblyDef);
            if (typeDef.Invalid != null)
                return true;

            if (usedTypes == null)
            {
                AccumUsedTypeAndMemberDefs(vctxt, assemblyDef, typeDef);
                if (Invalid != null)
                    return true;
            }

            foreach (var r in UsedTypes)
            {
                var usedAssemblyDef = default(AssemblyDef);
                var usedTypeDef = default(TypeDef);
                if (r.PrimTryResolve(vctxt.Global, out usedAssemblyDef, out usedTypeDef))
                    usedTypeDef.MarkAsUsed(vctxt, usedAssemblyDef);
            }
            foreach (var r in UsedMembers)
            {
                var usedAssemblyDef = default(AssemblyDef);
                var usedTypeDef = default(TypeDef);
                var usedMemberDef = default(MemberDef);
                if (r.PrimTryResolve(vctxt.Global, out usedAssemblyDef, out usedTypeDef, out usedMemberDef))
                    usedMemberDef.MarkAsUsed(vctxt, usedAssemblyDef, usedTypeDef);
            }

            return true;
        }
Exemplo n.º 46
0
 public override bool IncludeAttributes(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
 {
     return(HasFullReflection(assemblyDef, typeDef));
 }
Exemplo n.º 47
0
        internal void UsedByMembersClosure(Global global, AssemblyDef assemblyDef, TypeDef typeDef, Set<QualifiedMemberName> visitedMemberDefs, Seq<QualifiedMemberName> scc)
        {
            if (usedByMembers == null)
                return;

            var self = QualifiedMemberName(global, assemblyDef, typeDef);
            if (!visitedMemberDefs.Contains(self))
            {
                visitedMemberDefs.Add(self);
                scc.Add(self);
                foreach (var r in usedByMembers)
                {
                    var usedByAssemblyDef = default(AssemblyDef);
                    var usedByTypeDef = default(TypeDef);
                    var usedByMemberDef = default(MemberDef);
                    if (r.PrimTryResolve(global, out usedByAssemblyDef, out usedByTypeDef, out usedByMemberDef))
                        usedByMemberDef.UsedByMembersClosure
                            (global, usedByAssemblyDef, usedByTypeDef, visitedMemberDefs, scc);
                }
            }
        }
Exemplo n.º 48
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));
 }
Exemplo n.º 49
0
        internal void TopologicalTypeInit(Global global, AssemblyDef assemblyDef, TypeDef typeDef, Set<QualifiedTypeName> visitedTypeDefs, Seq<QualifiedTypeName> sortedTypeDefs, Set<QualifiedMemberName> visitedMemberDefs)
        {
            var self = QualifiedMemberName(global, assemblyDef, typeDef);
            if (visitedMemberDefs.Contains(self))
                return;
            visitedMemberDefs.Add(self);

            if (!IsUsed || Invalid != null || typeDef.Invalid != null)
                return;

            if (usedMembers != null)
            {
                foreach (var r in usedMembers)
                {
                    var usedAssemblyDef = default(AssemblyDef);
                    var usedTypeDef = default(TypeDef);
                    var usedMemberDef = default(MemberDef);
                    if (r.PrimTryResolve(global, out usedAssemblyDef, out usedTypeDef, out usedMemberDef))
                        usedMemberDef.TopologicalTypeInit
                            (global, usedAssemblyDef, usedTypeDef, visitedTypeDefs, sortedTypeDefs, visitedMemberDefs);
                }
            }

            TopologicalTypeInitFromImplementors
                (global, assemblyDef, typeDef, visitedTypeDefs, sortedTypeDefs, visitedMemberDefs);

            if (usedTypes != null)
            {
                foreach (var r in usedTypes)
                {
                    var usedAssemblyDef = default(AssemblyDef);
                    var usedTypeDef = default(TypeDef);
                    if (r.PrimTryResolve(global, out usedAssemblyDef, out usedTypeDef))
                        usedTypeDef.TopologicalTypeInit(global, usedAssemblyDef, visitedTypeDefs, sortedTypeDefs);
                }
            }
        }
Exemplo n.º 50
0
        public void AddAssembly(MessageContext ctxt, CST.AssemblyDef assemblyDef)
        {
            var assemblyTrace = ResolveAssemblyTrace(assemblyDef);

            assemblyTrace.AddAssembly(ctxt);
        }
Exemplo n.º 51
0
 public override MemberRef PrimReference(Global global, AssemblyDef assemblyDef, TypeDef typeDef, IImSeq<TypeRef> typeBoundArguments)
 {
     return new PolymorphicMethodRef
         (typeDef.PrimReference(global, assemblyDef, typeBoundArguments),
          Name,
          IsStatic,
          TypeArity,
          ValueParameters.Select(p => p.Type).ToSeq(),
          Result == null ? null : Result.Type);
 }
Exemplo n.º 52
0
        public void AddType(MessageContext ctxt, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
        {
            var assemblyTrace = ResolveAssemblyTrace(assemblyDef);;

            assemblyTrace.AddType(ctxt, typeDef);
        }
Exemplo n.º 53
0
        internal override void AccumUsedTypeAndMemberDefs(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef)
        {
            base.AccumUsedTypeAndMemberDefs(vctxt, assemblyDef, typeDef);
            var ctxt = MessageContextBuilders.Member(vctxt.Global, assemblyDef, typeDef, this);
            for (var i = 0; i < TypeParameters.Count; i++)
            {
                var p = TypeParameters[i];
                p.AccumUsedTypeDefs(vctxt, assemblyDef, false);
                if (p.Invalid != null)
                {
                    Invalid = new InvalidInfo(MessageContextBuilders.TypeArg(ParameterFlavor.Method, i), p.Invalid);
                    return;
                }
            }
            foreach (var p in ValueParameters)
            {
                Invalid = p.Type.AccumUsedTypeDefs(vctxt, ctxt, usedTypes);
                if (Invalid != null)
                    return;
            }
            if (Result != null)
            {
                Invalid = Result.Type.AccumUsedTypeDefs(vctxt, ctxt, usedTypes);
                if (Invalid != null)
                    return;
            }

            if (vctxt.IgnoreMethodDefBody(assemblyDef, typeDef, this))
                return;

            foreach (var l in Locals)
            {
                Invalid = l.Type.AccumUsedTypeDefs(vctxt, ctxt, usedTypes);
                if (Invalid != null)
                    return;
            }
            var instructions = Instructions(vctxt.Global);
            if (instructions != null)
            {
                foreach (var i in instructions.Body)
                {
                    Invalid = i.AccumUsedTypeAndMemberDefs(vctxt, ctxt, usedTypes, usedMembers);
                    if (Invalid != null)
                        return;
                }
            }
        }
Exemplo n.º 54
0
        public void AddMethod(MessageContext ctxt, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
        {
            var assemblyTrace = ResolveAssemblyTrace(assemblyDef);

            assemblyTrace.AddMethod(ctxt, typeDef, methodDef);
        }
Exemplo n.º 55
0
 public QualifiedMemberName QualifiedMemberName(Global global, AssemblyDef assemblyDef, TypeDef typeDef)
 {
     return new QualifiedMemberName(typeDef.QualifiedTypeName(global, assemblyDef), Signature);
 }
Exemplo n.º 56
0
 public string ResolveFieldDefToSlot(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.FieldDef fieldDef)
 {
     return(TypeMappingFor(assemblyDef, typeDef).ResolveFieldToSlot
                (fieldDef.QualifiedMemberName(env.Global, assemblyDef, typeDef)));
 }
Exemplo n.º 57
0
        //
        // References and environments
        //

        public abstract MemberRef PrimReference(Global global, AssemblyDef assemblyDef, TypeDef typeDef, IImSeq<TypeRef> typeBoundArguments);
Exemplo n.º 58
0
 public string ResolveAssemblyReferenceToSlot(CST.AssemblyDef assemblyDef, CST.AssemblyName assemblyName)
 {
     return(AssemblyMappingFor(assemblyDef).ResolveAssemblyReferenceToSlot(assemblyName));
 }
Exemplo n.º 59
0
 internal override void AccumUsedTypeAndMemberDefs(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef)
 {
     base.AccumUsedTypeAndMemberDefs(vctxt, assemblyDef, typeDef);
     var ctxt = MessageContextBuilders.Member(vctxt.Global, assemblyDef, typeDef, this);
     if (Add != null)
     {
         Invalid = Add.AccumUsedTypeDefs(vctxt, ctxt, usedTypes);
         if (Invalid != null)
             return;
     }
     if (Remove != null)
     {
         Invalid = Remove.AccumUsedTypeDefs(vctxt, ctxt, usedTypes);
         if (Invalid != null)
             return;
     }
     Invalid = HandlerType.AccumUsedTypeDefs(vctxt, ctxt, usedTypes);
 }
Exemplo n.º 60
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);
        }