public static TypeCompilerEnvironment EnterType
            (CompilerEnvironment env,
            JST.NameSupply nameSupply,
            JST.Identifier rootId,
            JST.Identifier assemblyId,
            JST.Identifier typeId,
            CST.TypeEnvironment typeEnv,
            TypeTrace typeTrace)
        {
            var typeBoundTypeParameterIds = new Seq <JST.Identifier>();

            for (var i = 0; i < typeEnv.Type.Arity; i++)
            {
                typeBoundTypeParameterIds.Add(nameSupply.GenSym());
            }

            var res = new TypeCompilerEnvironment
                          (typeEnv.Global,
                          typeEnv.SkolemDefs,
                          typeEnv.Assembly,
                          typeEnv.Type,
                          typeEnv.TypeBoundArguments,
                          env,
                          nameSupply,
                          rootId,
                          assemblyId,
                          typeId,
                          typeBoundTypeParameterIds,
                          typeTrace);

            res.BindSpecial();

            return(res);
        }
Example #2
0
        public MethodCompiler(TypeDefinitionCompiler parent, JST.NameSupply outerNameSupply, CST.MethodDef methodDef, MethodCompilationMode mode)
        {
            env = parent.Env;
            this.parent = parent;
            methEnv = parent.TyconEnv.AddSelfTypeBoundArguments().AddMethod(methodDef).AddSelfMethodBoundArguments();
            messageCtxt = CST.MessageContextBuilders.Env(methEnv);
            this.mode = mode;
            this.outerNameSupply = outerNameSupply;

            var common = default(JST.NameSupply);
            switch (mode)
            {
            case MethodCompilationMode.SelfContained:
                common = outerNameSupply;
                // Will be bound by function passed to root's BindMethod
                rootId = common.GenSym();
                assemblyId = common.GenSym();
                typeDefinitionId = common.GenSym();
                break;
            case MethodCompilationMode.DirectBind:
                common = outerNameSupply.Fork();
                // Already bound
                rootId = parent.RootId;
                assemblyId = parent.AssemblyId;
                typeDefinitionId = parent.TypeDefinitionId;
                break;
            default:
                throw new ArgumentOutOfRangeException("mode");
            }

            nameSupply = common.Fork();
            simpNameSupply = common.Fork();
        }
 private TypeCompilerEnvironment
     (CST.Global global,
     IImSeq <CST.SkolemDef> skolemDefs,
     CST.AssemblyDef assembly,
     CST.TypeDef type,
     IImSeq <CST.TypeRef> typeBoundArguments,
     CompilerEnvironment env,
     JST.NameSupply nameSupply,
     JST.Identifier rootId,
     JST.Identifier assemblyId,
     JST.Identifier typeId,
     IImSeq <JST.Identifier> typeBoundTypeParameterIds,
     TypeTrace typeTrace)
     : base(
         global,
         skolemDefs,
         assembly,
         type,
         typeBoundArguments)
 {
     this.env                  = env;
     NameSupply                = nameSupply;
     this.rootId               = rootId;
     this.assemblyId           = assemblyId;
     this.typeId               = typeId;
     TypeBoundTypeParameterIds = typeBoundTypeParameterIds;
     boundAssemblies           = new Map <CST.AssemblyName, JST.Expression>();
     boundTypes                = new Map <CST.TypeRef, ExpressionAndPhase>();
     this.typeTrace            = typeTrace;
 }
Example #4
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;
        }
        // Trace mode entry point
        public TypeDefinitionCompiler(AssemblyCompiler parent, TypeTrace typeTrace)
        {
            Env = parent.Env;
            Parent = parent;
            TyconEnv = parent.AssmEnv.AddType(typeTrace.Type);
            this.TypeTrace = typeTrace;

            if (typeTrace.IncludeType && typeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Create a self-loader fragment file
                NameSupply = new JST.NameSupply(Constants.Globals);
                // Will be bound by function passed to root's BindType
                RootId = NameSupply.GenSym();
                AssemblyId = NameSupply.GenSym();
                TypeDefinitionId = NameSupply.GenSym();
            }
            else {
                // Possibly inline type definition and/or method definitions into trace
                NameSupply = parent.NameSupply;
                // Already bound by parent
                RootId = parent.RootId;
                AssemblyId = parent.AssemblyId;
                // Will be bound locally
                TypeDefinitionId = NameSupply.GenSym();
            }
        }
Example #6
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
            }
        }
Example #7
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;
     }
 }
 private TypeCompilerEnvironment
     (CST.Global global,
      IImSeq<CST.SkolemDef> skolemDefs,
      CST.AssemblyDef assembly,
      CST.TypeDef type,
      IImSeq<CST.TypeRef> typeBoundArguments,
      CompilerEnvironment env,
      JST.NameSupply nameSupply,
      JST.Identifier rootId,
      JST.Identifier assemblyId,
      JST.Identifier typeId,
      IImSeq<JST.Identifier> typeBoundTypeParameterIds,
      TypeTrace typeTrace)
     : base(
         global,
         skolemDefs,
         assembly,
         type,
         typeBoundArguments)
 {
     this.env = env;
     NameSupply = nameSupply;
     this.rootId = rootId;
     this.assemblyId = assemblyId;
     this.typeId = typeId;
     TypeBoundTypeParameterIds = typeBoundTypeParameterIds;
     boundAssemblies = new Map<CST.AssemblyName, JST.Expression>();
     boundTypes = new Map<CST.TypeRef, ExpressionAndPhase>();
     this.typeTrace = typeTrace;
 }
Example #9
0
        // Trace mode entry point
        public TypeDefinitionCompiler(AssemblyCompiler parent, TypeTrace typeTrace)
        {
            Env            = parent.Env;
            Parent         = parent;
            TyconEnv       = parent.AssmEnv.AddType(typeTrace.Type);
            this.TypeTrace = typeTrace;

            if (typeTrace.IncludeType && typeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Create a self-loader fragment file
                NameSupply = new JST.NameSupply(Constants.Globals);
                // Will be bound by function passed to root's BindType
                RootId           = NameSupply.GenSym();
                AssemblyId       = NameSupply.GenSym();
                TypeDefinitionId = NameSupply.GenSym();
            }
            else
            {
                // Possibly inline type definition and/or method definitions into trace
                NameSupply = parent.NameSupply;
                // Already bound by parent
                RootId     = parent.RootId;
                AssemblyId = parent.AssemblyId;
                // Will be bound locally
                TypeDefinitionId = NameSupply.GenSym();
            }
        }
Example #10
0
 public Traces(CompilerEnvironment env)
 {
     Env             = env;
     TraceMap        = new Map <string, Trace>();
     AssemblyToTrace = new Map <CST.AssemblyName, Trace>();
     TypeToTrace     = new Map <CST.QualifiedTypeName, Trace>();
     MethodToTrace   = new Map <CST.QualifiedMemberName, Trace>();
 }
Example #11
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();
 }
Example #12
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();
 }
Example #13
0
 public TraceCompiler(CompilerEnvironment env, Trace trace)
 {
     Env   = env;
     Trace = trace;
     if (trace.Flavor != TraceFlavor.Remainder)
     {
         NameSupply = new JST.NameSupply(Constants.Globals);
         RootId     = NameSupply.GenSym();
     }
 }
Example #14
0
 public TraceCompiler(CompilerEnvironment env, Trace trace)
 {
     Env = env;
     Trace = trace;
     if (trace.Flavor != TraceFlavor.Remainder)
     {
         NameSupply = new JST.NameSupply(Constants.Globals);
         RootId = NameSupply.GenSym();
     }
 }
Example #15
0
 public TypeCompiler(TypeDefinitionCompiler parent)
 {
     // Type compiler is always in context of it's type definition
     Env = parent.Env;
     Parent = parent;
     var typeEnv = parent.TyconEnv.AddSelfTypeBoundArguments();
     NameSupply = typeEnv.Type.Arity > 0 ? parent.NameSupply.Fork() : parent.NameSupply;
     RootId = parent.RootId;
     AssemblyId = parent.AssemblyId;
     TypeDefinitionId = parent.TypeDefinitionId;
     TypeId = typeEnv.Type.Arity > 0 ? NameSupply.GenSym() : parent.TypeDefinitionId;
     TypeCompEnv = TypeCompilerEnvironment.EnterType(Env, NameSupply, RootId, AssemblyId, TypeId, typeEnv, parent.TypeTrace);
 }
 // Collecting mode entry point
 public TypeDefinitionCompiler(AssemblyCompiler parent, CST.TypeDef typeDef)
 {
     Env = parent.Env;
     Parent = parent;
     TyconEnv = parent.AssmEnv.AddType(typeDef);
     TypeTrace = null;
     // Inline type definition and method definitions into overall assembly
     NameSupply = parent.NameSupply;
     // Already bound by parent
     RootId = parent.RootId;
     AssemblyId = parent.AssemblyId;
     // Will be bound locally
     TypeDefinitionId = NameSupply.GenSym();
 }
Example #17
0
 // Collecting mode entry point
 public TypeDefinitionCompiler(AssemblyCompiler parent, CST.TypeDef typeDef)
 {
     Env       = parent.Env;
     Parent    = parent;
     TyconEnv  = parent.AssmEnv.AddType(typeDef);
     TypeTrace = null;
     // Inline type definition and method definitions into overall assembly
     NameSupply = parent.NameSupply;
     // Already bound by parent
     RootId     = parent.RootId;
     AssemblyId = parent.AssemblyId;
     // Will be bound locally
     TypeDefinitionId = NameSupply.GenSym();
 }
Example #18
0
 private MethodCompilerEnvironment
     (CST.Global global,
     IImSeq <CST.SkolemDef> skolemDefs,
     CST.AssemblyDef assembly,
     CST.TypeDef type,
     IImSeq <CST.TypeRef> typeBoundArguments,
     CST.MethodDef method,
     IImSeq <CST.TypeRef> methodBoundArguments,
     IMap <JST.Identifier, CST.Variable> variables,
     IImSeq <JST.Identifier> valueParameterIds,
     IImSeq <JST.Identifier> localIds,
     CompilerEnvironment env,
     JST.NameSupply nameSupply,
     JST.Identifier rootId,
     JST.Identifier assemblyId,
     JST.Identifier typeDefinitionId,
     JST.Identifier methodId,
     IImSeq <JST.Identifier> typeBoundTypeParameterIds,
     IImSeq <JST.Identifier> methodBoundTypeParameterIds,
     TypeTrace typeTrace)
     : base(
         global,
         skolemDefs,
         assembly,
         type,
         typeBoundArguments,
         method,
         methodBoundArguments,
         variables,
         valueParameterIds,
         localIds)
 {
     this.env                    = env;
     NameSupply                  = nameSupply;
     this.rootId                 = rootId;
     this.assemblyId             = assemblyId;
     this.typeDefinitionId       = typeDefinitionId;
     MethodId                    = methodId;
     TypeBoundTypeParameterIds   = typeBoundTypeParameterIds;
     MethodBoundTypeParameterIds = methodBoundTypeParameterIds;
     boundAssemblies             = new Map <CST.AssemblyName, JST.Expression>();
     boundTypes                  = new Map <CST.TypeRef, JST.Expression>();
     boundVariablePointers       = new Map <JST.Identifier, JST.Expression>();
     this.typeTrace              = typeTrace;
 }
Example #19
0
 public static MethodCompilerEnvironment EnterUntranslatedMethod
     (CompilerEnvironment env,
     JST.NameSupply outerNameSupply,
     JST.NameSupply nameSupply,
     JST.Identifier rootId,
     JST.Identifier assemblyId,
     JST.Identifier typeDefinitonId,
     CST.MethodEnvironment methEnv,
     TypeTrace typeTrace)
 {
     return(EnterMethod
                (env,
                outerNameSupply,
                nameSupply,
                rootId,
                assemblyId,
                typeDefinitonId,
                methEnv.AddVariables(nameSupply, i => false),
                typeTrace));
 }
Example #20
0
        // ----------------------------------------------------------------------
        // Last compilation times
        // ----------------------------------------------------------------------

        // TODO: Will return null if assembly def was compiled into a trace file...
        public static DateTime?LastCompilationTime(CompilerEnvironment env, CST.AssemblyName assemblyName, out string fn)
        {
            var assmName  = CST.CSTWriter.WithAppend(env.Global, CST.WriterStyle.Uniform, assemblyName.Append);
            var finalName = default(string);

            switch (env.CompilationMode)
            {
            case CompilationMode.Plain:
            case CompilationMode.Collecting:
                finalName = Constants.AllFileName;
                break;

            case CompilationMode.Traced:
                finalName = Constants.AssemblyFileName;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            fn = Path.Combine(Path.Combine(env.OutputDirectory, JST.Lexemes.StringToFileName(assmName)), finalName);
            return(File.Exists(fn) ? (DateTime?)File.GetLastWriteTimeUtc(fn) : null);
        }
Example #21
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);
            }
        }
Example #22
0
 public RuntimeCompiler(CompilerEnvironment env)
 {
     this.env = env;
 }
        public static TypeCompilerEnvironment EnterType
            (CompilerEnvironment env,
             JST.NameSupply nameSupply,
             JST.Identifier rootId,
             JST.Identifier assemblyId,
             JST.Identifier typeId,
             CST.TypeEnvironment typeEnv,
             TypeTrace typeTrace)
        {
            var typeBoundTypeParameterIds = new Seq<JST.Identifier>();
            for (var i = 0; i < typeEnv.Type.Arity; i++)
                typeBoundTypeParameterIds.Add(nameSupply.GenSym());

            var res = new TypeCompilerEnvironment
                (typeEnv.Global,
                 typeEnv.SkolemDefs,
                 typeEnv.Assembly,
                 typeEnv.Type,
                 typeEnv.TypeBoundArguments,
                 env,
                 nameSupply,
                 rootId,
                 assemblyId,
                 typeId,
                 typeBoundTypeParameterIds,
                 typeTrace);

            res.BindSpecial();

            return res;
        }
Example #24
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
            }
        }
Example #25
0
 public InlinedMethodCache(CompilerEnvironment env)
 {
     this.env      = env;
     bodySizeCache = new Map <CST.QualifiedMemberName, int>();
 }
Example #26
0
        public static MethodCompilerEnvironment EnterMethod
            (CompilerEnvironment env,
            JST.NameSupply outerNameSupply,
            JST.NameSupply nameSupply,
            JST.Identifier rootId,
            JST.Identifier assemblyId,
            JST.Identifier typeDefinitonId,
            CST.CompilationEnvironment compEnv,
            TypeTrace typeTrace)
        {
            // BUG: IE messes up scoping for function identifiers. To compensate we must allocate its
            //      identifier in the outer scope
            var methodId = outerNameSupply.GenSym();

            if (env.DebugMode)
            {
                var sb = new StringBuilder();
                sb.Append(methodId.Value);
                sb.Append('_');
                var namedTypeDef = compEnv.Type as CST.NamedTypeDef;
                if (namedTypeDef != null)
                {
                    if (namedTypeDef.Name.Namespace.Length > 0)
                    {
                        JST.Lexemes.AppendStringToIdentifier(sb, namedTypeDef.Name.Namespace.Replace('.', '_'));
                        sb.Append('_');
                    }
                    foreach (var n in namedTypeDef.Name.Types)
                    {
                        JST.Lexemes.AppendStringToIdentifier(sb, n);
                        sb.Append('_');
                    }
                }
                JST.Lexemes.AppendStringToIdentifier(sb, compEnv.Method.Name);
                methodId = new JST.Identifier(sb.ToString());
            }

            var typeBoundTypeParameterIds = new Seq <JST.Identifier>();

            for (var i = 0; i < compEnv.Type.Arity; i++)
            {
                typeBoundTypeParameterIds.Add(nameSupply.GenSym());
            }

            var methodBoundTypeParameterIds = new Seq <JST.Identifier>();

            for (var i = 0; i < compEnv.Method.TypeArity; i++)
            {
                methodBoundTypeParameterIds.Add(nameSupply.GenSym());
            }

            var res = new MethodCompilerEnvironment
                          (compEnv.Global,
                          compEnv.SkolemDefs,
                          compEnv.Assembly,
                          compEnv.Type,
                          compEnv.TypeBoundArguments,
                          compEnv.Method,
                          compEnv.MethodBoundArguments,
                          compEnv.Variables,
                          compEnv.ValueParameterIds,
                          compEnv.LocalIds,
                          env,
                          nameSupply,
                          rootId,
                          assemblyId,
                          typeDefinitonId,
                          methodId,
                          typeBoundTypeParameterIds,
                          methodBoundTypeParameterIds,
                          typeTrace);

            res.BindSpecial();

            return(res);
        }
Example #27
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;
        }
Example #28
0
 public RuntimeCompiler(CompilerEnvironment env)
 {
     this.env = env;
 }
Example #29
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;
        }
Example #30
0
        public static int Main(string[] args)
        {
            var env = new CompilerEnvironment();
            try
            {
                // Collect command line args
                var cl = new CompilerCommandLine(env.Log, env);
                cl.MergeFromArgs(args);

                if (env.CompilationMode == CompilationMode.Traced && env.TraceFileNames.Count == 0 && string.IsNullOrEmpty(env.FinalTraceName))
                {
                    env.Log(new UsageMessage("'-mode traced' must be accompanied by at least on of '-trace' or '-finalTraceName' options."));
                    throw new ExitException();
                }

                env.SetupPrimTracer();

                // ----------------------------------------
                // Load the assemblies
                // ----------------------------------------

                // Renames
                var subst = new CST.AssemblyNameSubstitution(env.Log, env.PrimTracer, env.AssemblyNameResolution);
                foreach (var r in env.RenameRules)
                    subst.Add(r);

                // Augmentations
                var augmentations = new CST.AugmentationDatabase(subst);
                foreach (var fn in env.AugmentationFileNames)
                    augmentations.AddFile(Path.Combine(env.InputDirectory, fn));
                foreach (var sn in env.OriginalStrongNames)
                    augmentations.AddOriginal(sn);

                // Final references
                var loadedAssemblies = new CST.LoadedAssemblyDatabase(augmentations);
                foreach (var fileName in env.ReferenceFileNames)
                    loadedAssemblies.Add(fileName, false);
                foreach (var fileName in env.CompileFileNames)
                    loadedAssemblies.Add(fileName, true);

                var loader = new CST.PELoader(loadedAssemblies);
                var global = loader.Load();

                // Done with the loader
                loader = null;

                env.SetupMetadata(global);

                try
                {
                    env.Validity.Check();

                    foreach (var assmInfo in loadedAssemblies)
                        env.Log(new CST.LoadedAssemblyMessage(assmInfo.TargetAssemblyName));

                    if (env.Tracer != null)
                        env.Tracer.Trace
                            ("Loaded assemblies",
                             w =>
                                 {
                                     foreach (var assemblyDef in global.Assemblies)
                                     {
                                         assemblyDef.Append(w);
                                         w.EndLine();
                                     }
                                 });

                    // ----------------------------------------
                    // Setup Interop
                    // ----------------------------------------
                    env.InteropManager.Setup();

                    // ----------------------------------------
                    // Collect assemblies
                    // ----------------------------------------

                    var allAssemblies = new Set<CST.AssemblyDef>();
                    var compilingAssemblies = new Set<CST.AssemblyDef>();
                    var referencedAssemblies = new Set<CST.AssemblyDef>();
                    var ok = true;
                    foreach (var assmInfo in loadedAssemblies)
                    {
                        var assembly = assmInfo.AssemblyDef;
                        allAssemblies.Add(assembly);
                        if (assmInfo.ForCompilation)
                        {
                            if (string.IsNullOrEmpty(env.OutputDirectory))
                            {
                                env.Log
                                    (new SkippingJavaScriptComplilation
                                         (assembly.Name, "No output directory was given"));
                                referencedAssemblies.Add(assembly);
                            }
                            else if (env.SkipUpToDate && IsUpToDate(env, assembly, false))
                            {
                                env.Log
                                    (new SkippingJavaScriptComplilation
                                         (assembly.Name, "Previously generated JavaScript is up to date"));
                                referencedAssemblies.Add(assembly);
                            }
                            else
                                compilingAssemblies.Add(assembly);
                        }
                        else
                        {
                            if (IsUpToDate(env, assembly, true))
                                referencedAssemblies.Add(assembly);
                            else
                                ok = false;
                        }
                    }

                    // Done with compilations
                    loadedAssemblies = null;                    

                    if (!ok)
                        throw new ExitException();

                    if (compilingAssemblies.Count > 0)
                    {
                        // ----------------------------------------
                        // Compile
                        // ----------------------------------------

                        switch (env.CompilationMode)
                        {
                        case CompilationMode.Plain:
                        case CompilationMode.Collecting:
                            // Compile all assemblies
                            foreach (var assemblyDef in compilingAssemblies)
                            {
                                var ac = new AssemblyCompiler(env, assemblyDef);
                                ac.Emit(null);
                            }
                            break;
                        case CompilationMode.Traced:
                            // Collect the trace file info
                            if (!string.IsNullOrEmpty(env.InitialTraceFileName))
                                env.Traces.Add(env.InitialTraceFileName, true);
                            foreach (var fn in env.TraceFileNames)
                                env.Traces.Add(fn, false);
                            env.Traces.AddFinalOrRemainder(env.FinalTraceName);
                            // Compile all traces and all remaining definitions
                            foreach (var kv in env.Traces.TraceMap)
                            {
                                var compiler = new TraceCompiler(env, kv.Value);
                                compiler.Emit();
                            }
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                        }

                        // ----------------------------------------
                        // Runtime
                        // ----------------------------------------

                        if (env.Global.Assemblies.Any(a => a.EntryPoint != null))
                        {
                            // Emit the runtime itself
                            var compiler = new RuntimeCompiler(env);
                            compiler.Emit();
                        }
                    }
                }
                finally
                {
                    env.Teardown();
                }
            }
            catch (ExitException)
            {
                // No-op
            }
            catch (Exception e)
            {
                Console.WriteLine("Internal error: {0}", e.Message);
                Console.WriteLine("Please report this error to the developers");
                env.NumErrors++;
            }
            finally
            {
                Console.WriteLine("{0} errors, {1} warnings", env.NumErrors, env.NumWarnings);
            }
            return env.NumErrors == 0 ? 0 : 1;
        }
Example #31
0
 private AssemblyCompiler(CompilerEnvironment env)
 {
     Env = env;
     moduleInitializer = null;
     typeDefs          = new Seq <CST.TypeDef>();
 }
Example #32
0
 public InlinedMethodCache(CompilerEnvironment env)
 {
     this.env = env;
     bodySizeCache = new Map<CST.QualifiedMemberName, int>();
 }
Example #33
0
 private AssemblyCompiler(CompilerEnvironment env)
 {
     Env = env;
     moduleInitializer = null;
     typeDefs = new Seq<CST.TypeDef>();
 }
Example #34
0
        // ----------------------------------------------------------------------
        // Last compilation times
        // ----------------------------------------------------------------------

        // TODO: Will return null if assembly def was compiled into a trace file...
        public static DateTime? LastCompilationTime(CompilerEnvironment env, CST.AssemblyName assemblyName, out string fn)
        {
            var assmName = CST.CSTWriter.WithAppend(env.Global, CST.WriterStyle.Uniform, assemblyName.Append);
            var finalName = default(string);
            switch (env.CompilationMode)
            {
            case CompilationMode.Plain:
            case CompilationMode.Collecting:
                finalName = Constants.AllFileName;
                break;
            case CompilationMode.Traced:
                finalName = Constants.AssemblyFileName;
                break;
            default:
                throw new ArgumentOutOfRangeException();
            }
            fn = Path.Combine(Path.Combine(env.OutputDirectory, JST.Lexemes.StringToFileName(assmName)), finalName);
            return File.Exists(fn) ? (DateTime?)File.GetLastWriteTimeUtc(fn) : null;
        }
Example #35
0
 public ValidityContext(CompilerEnvironment env)
     : base(env.Global, env.Log, env.Tracer)
 {
     this.env = env;
 }
Example #36
0
 public ValidityContext(CompilerEnvironment env)
     : base(env.Global, env.Log, env.Tracer)
 {
     this.env = env;
 }
Example #37
0
 public GlobalMapping(CompilerEnvironment env)
 {
     this.env = env;
     assemblyMappingCache = new Map<CST.AssemblyName, AssemblyMapping>();
     typeMappingCache = new Map<CST.QualifiedTypeName, TypeMapping>();
 }
Example #38
0
 public GlobalMapping(CompilerEnvironment env)
 {
     this.env             = env;
     assemblyMappingCache = new Map <CST.AssemblyName, AssemblyMapping>();
     typeMappingCache     = new Map <CST.QualifiedTypeName, TypeMapping>();
 }
Example #39
0
 public Traces(CompilerEnvironment env)
 {
     Env = env;
     TraceMap = new Map<string, Trace>();
     AssemblyToTrace = new Map<CST.AssemblyName, Trace>();
     TypeToTrace = new Map<CST.QualifiedTypeName, Trace>();
     MethodToTrace = new Map<CST.QualifiedMemberName, Trace>();
 }
Example #40
0
        public static int Main(string[] args)
        {
            var env = new CompilerEnvironment();

            try
            {
                // Collect command line args
                var cl = new CompilerCommandLine(env.Log, env);
                cl.MergeFromArgs(args);

                if (env.CompilationMode == CompilationMode.Traced && env.TraceFileNames.Count == 0 && string.IsNullOrEmpty(env.FinalTraceName))
                {
                    env.Log(new UsageMessage("'-mode traced' must be accompanied by at least on of '-trace' or '-finalTraceName' options."));
                    throw new ExitException();
                }

                env.SetupPrimTracer();

                // ----------------------------------------
                // Load the assemblies
                // ----------------------------------------

                // Renames
                var subst = new CST.AssemblyNameSubstitution(env.Log, env.PrimTracer, env.AssemblyNameResolution);
                foreach (var r in env.RenameRules)
                {
                    subst.Add(r);
                }

                // Augmentations
                var augmentations = new CST.AugmentationDatabase(subst);
                foreach (var fn in env.AugmentationFileNames)
                {
                    augmentations.AddFile(Path.Combine(env.InputDirectory, fn));
                }
                foreach (var sn in env.OriginalStrongNames)
                {
                    augmentations.AddOriginal(sn);
                }

                // Final references
                var loadedAssemblies = new CST.LoadedAssemblyDatabase(augmentations);
                foreach (var fileName in env.ReferenceFileNames)
                {
                    loadedAssemblies.Add(fileName, false);
                }
                foreach (var fileName in env.CompileFileNames)
                {
                    loadedAssemblies.Add(fileName, true);
                }

                var loader = new CST.PELoader(loadedAssemblies);
                var global = loader.Load();

                // Done with the loader
                loader = null;

                env.SetupMetadata(global);

                try
                {
                    env.Validity.Check();

                    foreach (var assmInfo in loadedAssemblies)
                    {
                        env.Log(new CST.LoadedAssemblyMessage(assmInfo.TargetAssemblyName));
                    }

                    if (env.Tracer != null)
                    {
                        env.Tracer.Trace
                            ("Loaded assemblies",
                            w =>
                        {
                            foreach (var assemblyDef in global.Assemblies)
                            {
                                assemblyDef.Append(w);
                                w.EndLine();
                            }
                        });
                    }

                    // ----------------------------------------
                    // Setup Interop
                    // ----------------------------------------
                    env.InteropManager.Setup();

                    // ----------------------------------------
                    // Collect assemblies
                    // ----------------------------------------

                    var allAssemblies        = new Set <CST.AssemblyDef>();
                    var compilingAssemblies  = new Set <CST.AssemblyDef>();
                    var referencedAssemblies = new Set <CST.AssemblyDef>();
                    var ok = true;
                    foreach (var assmInfo in loadedAssemblies)
                    {
                        var assembly = assmInfo.AssemblyDef;
                        allAssemblies.Add(assembly);
                        if (assmInfo.ForCompilation)
                        {
                            if (string.IsNullOrEmpty(env.OutputDirectory))
                            {
                                env.Log
                                    (new SkippingJavaScriptComplilation
                                        (assembly.Name, "No output directory was given"));
                                referencedAssemblies.Add(assembly);
                            }
                            else if (env.SkipUpToDate && IsUpToDate(env, assembly, false))
                            {
                                env.Log
                                    (new SkippingJavaScriptComplilation
                                        (assembly.Name, "Previously generated JavaScript is up to date"));
                                referencedAssemblies.Add(assembly);
                            }
                            else
                            {
                                compilingAssemblies.Add(assembly);
                            }
                        }
                        else
                        {
                            if (IsUpToDate(env, assembly, true))
                            {
                                referencedAssemblies.Add(assembly);
                            }
                            else
                            {
                                ok = false;
                            }
                        }
                    }

                    // Done with compilations
                    loadedAssemblies = null;

                    if (!ok)
                    {
                        throw new ExitException();
                    }

                    if (compilingAssemblies.Count > 0)
                    {
                        // ----------------------------------------
                        // Compile
                        // ----------------------------------------

                        switch (env.CompilationMode)
                        {
                        case CompilationMode.Plain:
                        case CompilationMode.Collecting:
                            // Compile all assemblies
                            foreach (var assemblyDef in compilingAssemblies)
                            {
                                var ac = new AssemblyCompiler(env, assemblyDef);
                                ac.Emit(null);
                            }
                            break;

                        case CompilationMode.Traced:
                            // Collect the trace file info
                            if (!string.IsNullOrEmpty(env.InitialTraceFileName))
                            {
                                env.Traces.Add(env.InitialTraceFileName, true);
                            }
                            foreach (var fn in env.TraceFileNames)
                            {
                                env.Traces.Add(fn, false);
                            }
                            env.Traces.AddFinalOrRemainder(env.FinalTraceName);
                            // Compile all traces and all remaining definitions
                            foreach (var kv in env.Traces.TraceMap)
                            {
                                var compiler = new TraceCompiler(env, kv.Value);
                                compiler.Emit();
                            }
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }

                        // ----------------------------------------
                        // Runtime
                        // ----------------------------------------

                        if (env.Global.Assemblies.Any(a => a.EntryPoint != null))
                        {
                            // Emit the runtime itself
                            var compiler = new RuntimeCompiler(env);
                            compiler.Emit();
                        }
                    }
                }
                finally
                {
                    env.Teardown();
                }
            }
            catch (ExitException)
            {
                // No-op
            }
            catch (Exception e)
            {
                Console.WriteLine("Internal error: {0}", e.Message);
                Console.WriteLine("Please report this error to the developers");
                env.NumErrors++;
            }
            finally
            {
                Console.WriteLine("{0} errors, {1} warnings", env.NumErrors, env.NumWarnings);
            }
            return(env.NumErrors == 0 ? 0 : 1);
        }
Example #41
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;
        }