A wrapper for a TextWriter instance that adds various methods for emitting source code in a nicely formatted way. The formatting conventions can be specified via options.
    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"));
    }
示例#2
0
    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);
    }