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); }
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; }
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(); } }
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 } }
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; }
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>(); }
// 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(); }
public TraceCompiler(CompilerEnvironment env, Trace trace) { Env = env; Trace = trace; if (trace.Flavor != TraceFlavor.Remainder) { NameSupply = new JST.NameSupply(Constants.Globals); RootId = NameSupply.GenSym(); } }
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(); }
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; }
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)); }
// ---------------------------------------------------------------------- // 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); }
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); } }
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; }
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 } }
public InlinedMethodCache(CompilerEnvironment env) { this.env = env; bodySizeCache = new Map <CST.QualifiedMemberName, int>(); }
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); }
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; }
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; }
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; }
private AssemblyCompiler(CompilerEnvironment env) { Env = env; moduleInitializer = null; typeDefs = new Seq <CST.TypeDef>(); }
public InlinedMethodCache(CompilerEnvironment env) { this.env = env; bodySizeCache = new Map<CST.QualifiedMemberName, int>(); }
private AssemblyCompiler(CompilerEnvironment env) { Env = env; moduleInitializer = null; typeDefs = new Seq<CST.TypeDef>(); }
// ---------------------------------------------------------------------- // 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; }
public ValidityContext(CompilerEnvironment env) : base(env.Global, env.Log, env.Tracer) { this.env = env; }
public GlobalMapping(CompilerEnvironment env) { this.env = env; assemblyMappingCache = new Map<CST.AssemblyName, AssemblyMapping>(); typeMappingCache = new Map<CST.QualifiedTypeName, TypeMapping>(); }
public GlobalMapping(CompilerEnvironment env) { this.env = env; assemblyMappingCache = new Map <CST.AssemblyName, AssemblyMapping>(); typeMappingCache = new Map <CST.QualifiedTypeName, TypeMapping>(); }
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>(); }
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); }
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; }