internal Translator(IMetadataHost host, IModule module, IAssembly mscorlib, SourceEmitter source, SourceEmitter header, string location, PdbReader/*?*/ pdbReader) { Contract.Requires(host != null); Contract.Requires(module != null); Contract.Requires(mscorlib != null); Contract.Requires(source != null); Contract.Requires(header != null); Contract.Requires(location != null); this.host = host; this.module = module; this.pdbReader = pdbReader; this.currentBody = Dummy.MethodBody; this.source = source; this.header = header; this.location = location; this.sourceEmitter = header; this.arithmeticExceptionType = UnitHelper.FindType(host.NameTable, mscorlib, "System.ArithmeticException"); this.contextBoundObject = UnitHelper.FindType(host.NameTable, mscorlib, "System.ContextBoundObject"); this.cRuntimeAttribute = UnitHelper.FindType(host.NameTable, mscorlib, "System.CRuntimeAttribute"); this.divideByZeroExceptionType = UnitHelper.FindType(host.NameTable, mscorlib, "System.DivideByZeroException"); this.doNotMangleAttribute = UnitHelper.FindType(host.NameTable, mscorlib, "System.Runtime.CompilerServices.DoNotMangleAttribute"); this.invalidCastExceptionType = UnitHelper.FindType(host.NameTable, mscorlib, "System.InvalidCastException"); this.marshalByRefObject = UnitHelper.FindType(host.NameTable, mscorlib, "System.MarshalByRefObject"); this.overflowExceptionType = UnitHelper.FindType(host.NameTable, mscorlib, "System.OverflowException"); this.outOfMemoryExceptionType = UnitHelper.FindType(host.NameTable, mscorlib, "System.OutOfMemoryException"); this.runtimeHelpers = UnitHelper.FindType(host.NameTable, mscorlib, "System.Runtime.CompilerServices.RuntimeHelpers"); this.runtimeType = UnitHelper.FindType(host.NameTable, mscorlib, "System.RuntimeType"); this.stackOverflowExceptionType = UnitHelper.FindType(host.NameTable, mscorlib, "System.StackOverflowException"); this.nullReferenceExceptionType = UnitHelper.FindType(host.NameTable, mscorlib, "System.NullReferenceException"); this.threadStaticAttribute = UnitHelper.FindType(host.NameTable, mscorlib, "System.ThreadStaticAttribute"); this.vaListType = UnitHelper.FindType(host.NameTable, mscorlib, "System.CRuntime.va_list"); this.callFunctionPointer = host.NameTable.GetNameFor("CallFunctionPointer"); this.callFunctionPointer2 = host.NameTable.GetNameFor("CallFunctionPointer2"); this.getAs = host.NameTable.GetNameFor("GetAs"); this.getAsPointer = host.NameTable.GetNameFor("GetAsPointer"); this.getOffsetToStringData = host.NameTable.GetNameFor("get_OffsetToStringData"); this.baseClass0 = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("baseClass0")); this.baseClass1 = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("baseClass1")); this.baseClass2 = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("baseClass2")); this.baseClass3 = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("baseClass3")); this.baseClass4 = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("baseClass4")); this.baseClass5 = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("baseClass5")); this.baseClasses6andBeyond = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("baseClasses6andBeyond")); this.directInterfacesField = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("directlyImplementedInterfaces")); this.implementedInterfaceMapField = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("implementedInterfaceMap")); this.genericArgumentsField = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("genericArguments")); this.defaultConstructorField = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("defaultConstructor")); this.interfaceIndexField = TypeHelper.GetField(host.PlatformType.SystemType.ResolvedType, host.NameTable.GetNameFor("interfaceIndex")); this.stringEmptyField = TypeHelper.GetField(host.PlatformType.SystemString.ResolvedType, host.NameTable.GetNameFor("Empty")); this.typeField = TypeHelper.GetField(host.PlatformType.SystemObject.ResolvedType, host.NameTable.GetNameFor("type")); this.delegateTargetField = TypeHelper.GetField(host.PlatformType.SystemDelegate.ResolvedType, host.NameTable.GetNameFor("_target")); this.delegateIsStaticField = TypeHelper.GetField(host.PlatformType.SystemDelegate.ResolvedType, host.NameTable.GetNameFor("_isStatic")); this.delegateMethodPtrField = TypeHelper.GetField(host.PlatformType.SystemDelegate.ResolvedType, host.NameTable.GetNameFor("_methodPtr")); }
static void Main(string[] args) { if (args == null || args.Length == 0) { Console.WriteLine("usage: ILtoC [path]fileName.ext"); return; } using (var host = new Host()) { var mscorlib = host.LoadUnitFrom("mscorlib.dll") as IAssembly; if (mscorlib == null || mscorlib is Dummy) { Console.WriteLine("mscorlib.dll must be in the same directory as "+args[0]); return; } var coreIdentity = host.CoreAssemblySymbolicIdentity; //Force the host to select the local mscorlib as the core assembly. if (coreIdentity != mscorlib.AssemblyIdentity) { Console.WriteLine("bug in host"); return; } var module = host.LoadUnitFrom(args[0]) as IModule; if (module == null || module is Dummy) { Console.WriteLine(args[0]+" is not a PE file containing a CLR module or assembly."); return; } var moduleLocation = args[0]; Contract.Assume(moduleLocation.Length > 0); PdbReader/*?*/ pdbReader = null; string pdbFileName = Path.ChangeExtension(moduleLocation, "pdb"); if (File.Exists(pdbFileName)) { using (var pdbStream = File.OpenRead(pdbFileName)) { pdbReader = new PdbReader(pdbStream, host); } } var cfile = Path.ChangeExtension(moduleLocation, ".c"); var hfile = Path.ChangeExtension(moduleLocation, ".h"); var moduleFileName = Path.GetFileName(moduleLocation); Contract.Assume(moduleFileName != null && moduleFileName.Length > 0); string location = Path.GetFullPath(moduleLocation).Replace(moduleFileName, ""); ; using (var cStreamWriter = File.CreateText(cfile)) { using (var hStreamWriter = File.CreateText(hfile)) { var cEmitter = new SourceEmitter(cStreamWriter); cEmitter.EmitString("#include \""); cEmitter.EmitString(hfile); cEmitter.EmitString("\""); cEmitter.EmitNewLine(); var hEmitter = new SourceEmitter(hStreamWriter); new Translator(host, module, mscorlib, cEmitter, hEmitter, location, pdbReader).TranslateToC(); } } } }
private void EmitBody(Hashtable<ITypeReference> closedStructuralTypeInstancesUsedInThisModule) { Contract.Requires(closedStructuralTypeInstancesUsedInThisModule != null); this.sourceEmitter = this.source; IEnumerable<string> literalStrings = null; Hashtable<ITypeReference> allClosedStructuralTypeInstances = null; Hashtable<IGenericMethodInstanceReference> allClosedGenericMethodInstances = null; if (this.module.Kind == ModuleKind.ConsoleApplication || this.module.Kind == ModuleKind.WindowsApplication) { //We need one definition of these per executable. this.sourceEmitter.EmitString("// Uncomment the following line to enable __debugbreak() in the event of an exception been thrown"); this.sourceEmitter.EmitNewLine(); this.sourceEmitter.EmitString("// #define ENABLE_DEBUG_BREAK"); this.sourceEmitter.EmitNewLine(); this.sourceEmitter.EmitString("uint32_t appdomain_static_block_size;"); this.sourceEmitter.EmitNewLine(); this.sourceEmitter.EmitString("tls_type appdomain_static_block_tlsIndex;"); this.sourceEmitter.EmitNewLine(); this.sourceEmitter.EmitString("uint32_t interfaceMethodIDCounter;"); this.sourceEmitter.EmitNewLine(); this.sourceEmitter.EmitString("uint8_t* statics;"); this.sourceEmitter.EmitNewLine(); this.sourceEmitter.EmitString("uint32_t thread_static_block_size;"); this.sourceEmitter.EmitNewLine(); this.sourceEmitter.EmitString("tls_type thread_static_block_tlsIndex;"); this.sourceEmitter.EmitNewLine(); var allModules = this.GetThisAndAllReferencedModules(); var allNominalTypes = this.GetAllNominalTypes(allModules); allClosedStructuralTypeInstances = this.GetAllClosedStructuralTypeInstanceReferencesIn(allModules, out allClosedGenericMethodInstances); literalStrings = this.GetAllLiteralStringsIn(allModules); this.EmitAllocatorForStaticVariables(allNominalTypes, allClosedStructuralTypeInstances); this.EmitMain(); } else { //Since this module is not the executable, we wont emit static variable definitions for things that are //defined by structure (and thus do not live in a particular module). All such things are defined, once, //in the the executable. The header for the current module will contain external references to these definitions. } this.EmitStaticVariables(allClosedStructuralTypeInstances, literalStrings, doingHeader: false); this.EmitTypeLoader(closedStructuralTypeInstancesUsedInThisModule, literalStrings); this.EmitMethods(allClosedStructuralTypeInstances, allClosedGenericMethodInstances); }
private void EmitHeader(Hashtable<ITypeReference> closedStructuralTypeInstances, Hashtable<IGenericMethodInstanceReference> closedGenericMethodInstances) { Contract.Requires(closedStructuralTypeInstances != null); this.sourceEmitter = this.header; var literalStrings = this.module.GetStrings(); this.EmitReferences(); this.EmitStructs(closedStructuralTypeInstances); this.EmitStaticVariables(closedStructuralTypeInstances, literalStrings, doingHeader: true); this.EmitMethodSignatures(closedStructuralTypeInstances, closedGenericMethodInstances); }