Пример #1
0
 private void EmitStructs(Hashtable<ITypeReference> closedStructuralTypeInstances) {
   var emittedTypes = new SetOfUints();
   foreach (var type in this.module.GetAllTypes()) {
     Contract.Assume(type != null);
     if (TypeHelper.HasOwnOrInheritedTypeParameters(type)) continue;
     this.EmitStruct(type, emittedTypes);
   }
   if (closedStructuralTypeInstances != null) {
     foreach (var structuralTypeInstance in closedStructuralTypeInstances.Values) {
       Contract.Assume(structuralTypeInstance != null);
       this.EmitStruct(structuralTypeInstance.ResolvedType, emittedTypes);
     }
   }
 }
Пример #2
0
 private void EmitTypeLoadingCallsFor(IManagedPointerTypeReference managedPointerType, string mangledName, SetOfUints alreadyLoadedTypes) {
   Contract.Requires(managedPointerType != null);
   Contract.Requires(mangledName != null);
   Contract.Requires(alreadyLoadedTypes != null);
   //TODO: implement this
   this.EmitSetTypeAndSetBaseClass((ITypeReference)managedPointerType, mangledName, alreadyLoadedTypes);
 }
Пример #3
0
    private void EmitTypeLoadingCallsFor(IArrayTypeReference arrayType, string typeObjectName, SetOfUints alreadyLoadedTypes) {
      Contract.Requires(arrayType != null);
      Contract.Requires(typeObjectName != null);
      Contract.Requires(alreadyLoadedTypes != null);

      var elementTypeObjectName = this.GetMangledTypeName(arrayType.ElementType)+"_typeObject";
      this.EmitTypeLoadingCallsFor(arrayType.ElementType, elementTypeObjectName, alreadyLoadedTypes);
      if (arrayType.IsVector) {
        this.sourceEmitter.EmitString("GetVectorType(");
        this.sourceEmitter.EmitString(elementTypeObjectName);
      } else {
        this.sourceEmitter.EmitString("GetMatrixType(");
        this.sourceEmitter.EmitString(elementTypeObjectName);
        this.sourceEmitter.EmitString(", "+arrayType.Rank);
      }
      this.sourceEmitter.EmitString(", (uintptr_t)&");
      this.sourceEmitter.EmitString(typeObjectName);
      this.sourceEmitter.EmitString(");");
      this.sourceEmitter.EmitNewLine();
    }
Пример #4
0
    private void EmitTypeLoadingCallsFor(INestedTypeReference nestedType, string typeObjectName, SetOfUints alreadyLoadedTypes) {
      Contract.Requires(nestedType != null);
      Contract.Requires(typeObjectName != null);
      Contract.Requires(alreadyLoadedTypes != null);

      var containingTypeObjectName = this.GetMangledTypeName(nestedType.ContainingType)+"_typeObject";
      this.EmitTypeLoadingCallsFor(nestedType.ContainingType, containingTypeObjectName, alreadyLoadedTypes);
      this.EmitSetTypeAndSetBaseClass(nestedType.ResolvedType, typeObjectName, alreadyLoadedTypes);
      this.sourceEmitter.EmitString("SetDeclaringType(");
      this.sourceEmitter.EmitString(typeObjectName);
      this.sourceEmitter.EmitString(", ");
      this.sourceEmitter.EmitString(containingTypeObjectName);
      this.sourceEmitter.EmitString(");");
      this.sourceEmitter.EmitNewLine();
    }
Пример #5
0
    private void EmitTypeLoadingCallsFor(IGenericTypeInstanceReference genericTypeInstance, string typeObjectName, SetOfUints alreadyLoadedTypes) {
      Contract.Requires(genericTypeInstance != null);
      Contract.Requires(typeObjectName != null);
      Contract.Requires(alreadyLoadedTypes != null);

      this.EmitSetTypeAndSetBaseClass(genericTypeInstance.ResolvedType, typeObjectName, alreadyLoadedTypes);
      this.sourceEmitter.EmitString("AllocateForGenericArguments(");
      this.sourceEmitter.EmitString(typeObjectName);
      this.sourceEmitter.EmitString(", " + genericTypeInstance.GenericType.GenericParameterCount + ");");
      this.sourceEmitter.EmitNewLine();
      int count = 0;
      foreach (var genericArgument in genericTypeInstance.GenericArguments) {
        Contract.Assume(genericArgument != null);
        this.sourceEmitter.EmitString("SetGenericArgument(");
        this.sourceEmitter.EmitString(typeObjectName);
        this.sourceEmitter.EmitString(", ");
        this.sourceEmitter.EmitString(this.GetMangledTypeName(genericArgument)+"_typeObject");
        this.sourceEmitter.EmitString(", " + count + ");");
        this.sourceEmitter.EmitNewLine();
        count++;
      }
    }
Пример #6
0
    private void EmitTypeLoadingCallsFor(ITypeReference typeRef, string typeObjectName, SetOfUints alreadyLoadedTypes) {
      Contract.Requires(typeRef != null);
      Contract.Requires(typeObjectName != null);
      Contract.Requires(alreadyLoadedTypes != null);

      var genericTypeInstance = typeRef as IGenericTypeInstanceReference;
      if (genericTypeInstance != null)
        this.EmitTypeLoadingCallsFor(genericTypeInstance, typeObjectName, alreadyLoadedTypes);
      else {
        var nestedType = typeRef as INestedTypeReference;
        if (nestedType != null)
          this.EmitTypeLoadingCallsFor(nestedType, typeObjectName, alreadyLoadedTypes);
        else {
          var arrayType = typeRef as IArrayTypeReference;
          if (arrayType != null)
            this.EmitTypeLoadingCallsFor(arrayType, typeObjectName, alreadyLoadedTypes);
          else {
            var pointerTypeRef = typeRef as IPointerTypeReference;
            if (pointerTypeRef != null)
              this.EmitTypeLoadingCallsFor(pointerTypeRef, typeObjectName, alreadyLoadedTypes);
            else {
              var managedPointerTypeRef = typeRef as IManagedPointerTypeReference;
              if (managedPointerTypeRef != null)
                this.EmitTypeLoadingCallsFor(managedPointerTypeRef, typeObjectName, alreadyLoadedTypes);
              else {
                this.EmitSetTypeAndSetBaseClass(typeRef, typeObjectName, alreadyLoadedTypes);
              }
            }
          }
        }
      }
    }
Пример #7
0
    private void LoadTypesDefinedInThisModule(Hashtable<ITypeReference> closedStructuralTypeInstancesUsedInThisModule) {
      Contract.Requires(closedStructuralTypeInstancesUsedInThisModule != null);

      this.sourceEmitter.EmitString("GetNewModule((uintptr_t)&_module);");
      this.sourceEmitter.EmitNewLine();
      this.CreateNewVmtForType(this.host.PlatformType.SystemObject.ResolvedType);
      List<IMethodReference> systemObjectVmt = this.vmts[this.host.PlatformType.SystemObject.ResolvedType.InternedKey];
      Hashtable systemObjectVmtHashTable = this.vmtHashTable[this.host.PlatformType.SystemObject.ResolvedType.InternedKey];
      var mangledRuntimeTypeName = this.GetMangledTypeName(this.runtimeType);

      //First create objects for all types in this module (referenced modules already have had their types loaded).
      foreach (var type in this.module.GetAllTypes()) {
        Contract.Assume(type != null);        
        if (TypeHelper.HasOwnOrInheritedTypeParameters(type)) continue; // We do not generate type objects for generic templates
        List<IMethodReference> vmt;
        if (type.InternedKey != this.host.PlatformType.SystemObject.InternedKey)
          vmt = this.GetVmtForType(type);
        else
          vmt = systemObjectVmt;
        this.EmitCreateNewTypeObject(vmt, mangledRuntimeTypeName, type);
      }

      //We also need objects for the structural type instances used in this module since some of them might be base classes.
      foreach (var type in closedStructuralTypeInstancesUsedInThisModule.Values) {
        Contract.Assume(type != null);
        List<IMethodReference> vmt = this.GetVmtForType(type.ResolvedType);
        this.EmitCreateNewTypeObject(vmt, mangledRuntimeTypeName, type.ResolvedType, isStructuralType: true);
      }

      this.sourceEmitter.EmitNewLine();
      //Now set the base class of each of the type objects created above.
      //A type cannot be set as the base class of another type before its own base class has been set,
      //so EmitSetBaseClass will walk the base class chain to ensure this.
      var alreadyProcessed = new SetOfUints(); //hence the need for this set.
      foreach (var type in this.module.GetAllTypes()) {
        Contract.Assume(type != null);

        if (TypeHelper.HasOwnOrInheritedTypeParameters(type)) continue; // We do not generate type objests for generic templates
        var typeObjectName = this.GetMangledTypeName(type)+"_typeObject";
        this.EmitTypeLoadingCallsFor(type, typeObjectName, alreadyProcessed);
      }
      foreach (var type in closedStructuralTypeInstancesUsedInThisModule.Values) {
        Contract.Assume(type != null);
        var typeObjectName = this.GetMangledTypeName(type)+"_typeObject";
        this.EmitTypeLoadingCallsFor(type, typeObjectName, alreadyProcessed);
      }
    }
Пример #8
0
 private void LoadVmtsOfReferencedModules() {
   var types = new SetOfUints();
   foreach (var referencedAssembly in this.module.AssemblyReferences) {
     Contract.Assume(referencedAssembly != null);
     foreach (var type in referencedAssembly.ResolvedAssembly.GetAllTypes()) {
       Contract.Assume(type != null);
       if (!types.Add(type.InternedKey)) continue;
       if (type.InternedKey != this.host.PlatformType.SystemObject.InternedKey)
         this.GetVmtForType(type);
     }
   }
   foreach (var referencedModule in this.module.ModuleReferences) {
     Contract.Assume(referencedModule != null);
     foreach (var type in referencedModule.ResolvedModule.GetAllTypes()) {
       Contract.Assume(type != null);
       if (!types.Add(type.InternedKey)) continue;
       if (type.InternedKey != this.host.PlatformType.SystemObject.InternedKey)
         this.GetVmtForType(type);
     }
   }
 }
Пример #9
0
    private void EmitStruct(ITypeDefinition type, SetOfUints emittedTypes) {
      Contract.Requires(type != null);
      Contract.Requires(emittedTypes != null);

      if (!emittedTypes.Add(type.InternedKey)) return;

      var instanceType = type;
      var instanceFields = this.GetInstanceFields(instanceType);
      foreach (var field in instanceFields) {
        Contract.Assume(field != null);
        var ft = field.Type.ResolvedType;
        if (ft is IGenericParameter) continue;
        if (ft.IsValueType && (ft is IGenericTypeInstance || TypeHelper.GetDefiningUnit(ft) == this.module) && !emittedTypes.Contains(ft.InternedKey)) {
          this.EmitStruct(ft, emittedTypes);
        }
      }
      if (this.sourceEmitter.LeaveBlankLinesBetweenNamespaceMembers) this.sourceEmitter.EmitNewLine();
      var mangledName = this.GetMangledTypeName(type);
      this.sourceEmitter.EmitString("extern uintptr_t "+mangledName+"_typeObject;");     
      this.sourceEmitter.EmitNewLine();
      if (type.IsInterface) return;
      this.sourceEmitter.EmitString("#ifndef struct_");
      this.sourceEmitter.EmitString(mangledName);
      this.sourceEmitter.EmitNewLine();
      this.sourceEmitter.EmitString("#define struct_");
      this.sourceEmitter.EmitString(mangledName);
      this.sourceEmitter.EmitNewLine();

      this.sourceEmitter.EmitString("struct ");
      this.sourceEmitter.EmitString(mangledName);
      this.sourceEmitter.EmitTypeBodyOpeningDelimiter(" {");
      this.sourceEmitter.EmitNewLine();
      foreach (var field in instanceFields) {
        Contract.Assume(field != null);
        this.EmitInstanceField(field);
      }
      if (instanceFields.Count == 0) {
        var size = type.SizeOf;
        if (size == 0) size = 1;
        this.sourceEmitter.EmitString("char dummy["+size+"];");
        this.sourceEmitter.EmitNewLine();
      }
      this.sourceEmitter.EmitBlockClosingDelimiter("};");
      this.sourceEmitter.EmitNewLine();
      if (!type.IsValueType) {
        this.sourceEmitter.EmitString("#endif");
        this.sourceEmitter.EmitNewLine();
        return;
      }

      //Emit unboxed version of type.
      uint fieldCount = 0;
      this.sourceEmitter.EmitString("struct ");
      this.sourceEmitter.EmitString(mangledName);
      this.sourceEmitter.EmitString("_unboxed");
      this.sourceEmitter.EmitTypeBodyOpeningDelimiter(" {");
      this.sourceEmitter.EmitNewLine();
      foreach (var field in instanceFields) {
        Contract.Assume(field != null);
        if (field.ContainingTypeDefinition != instanceType) continue;
        fieldCount++;
        this.EmitInstanceField(field);
      }
      if (fieldCount == 0) {
        var size = type.SizeOf;
        if (size == 0) size = 1;
        this.sourceEmitter.EmitString("char dummy["+size+"];");
        this.sourceEmitter.EmitNewLine();
      }
      this.sourceEmitter.EmitBlockClosingDelimiter("};");
      this.sourceEmitter.EmitNewLine();

      this.sourceEmitter.EmitString("#endif");
      this.sourceEmitter.EmitNewLine();
    }
Пример #10
0
    private void EmitSetInterface(ITypeReference type, string mangledName, SetOfUints alreadyProcessed) {
      Contract.Requires(type != null);
      Contract.Requires(mangledName != null);
      Contract.Requires(alreadyProcessed != null);

      if (!alreadyProcessed.Add(type.InternedKey)) return;
    }
Пример #11
0
    private void EmitSetTypeAndSetBaseClass(ITypeReference type, string mangledName, SetOfUints alreadyProcessed) {
      Contract.Requires(type != null);
      Contract.Requires(mangledName != null);
      Contract.Requires(alreadyProcessed != null);

      if (!alreadyProcessed.Add(type.InternedKey)) return;

      bool typeMayAlreadyBeInitialized = TypeHelper.GetDefiningUnit(type.ResolvedType) != this.module;
      if (typeMayAlreadyBeInitialized) {
        this.sourceEmitter.EmitString("if (*((uintptr_t*)(");
        this.sourceEmitter.EmitString(mangledName);
        this.sourceEmitter.EmitString("+sizeof(void*)*2)) == 0) ");
        this.sourceEmitter.EmitBlockOpeningDelimiter("{");
        this.sourceEmitter.EmitNewLine();
      }

      this.sourceEmitter.EmitString("SetType(");
      this.sourceEmitter.EmitString(mangledName);
      this.sourceEmitter.EmitString(", ");
      this.sourceEmitter.EmitString(this.GetMangledTypeName(this.host.PlatformType.SystemType));
      this.sourceEmitter.EmitString("_typeObject);");
      this.sourceEmitter.EmitNewLine();

      foreach (var baseClass in type.ResolvedType.BaseClasses) {
        var mangledBaseClassName = this.GetMangledTypeName(baseClass)+"_typeObject";
        this.EmitSetTypeAndSetBaseClass(baseClass, mangledBaseClassName, alreadyProcessed);
        this.sourceEmitter.EmitString("SetBaseClass(");
        this.sourceEmitter.EmitString(mangledName);
        this.sourceEmitter.EmitString(", ");
        this.sourceEmitter.EmitString(mangledBaseClassName);
        this.sourceEmitter.EmitString(");");
        this.sourceEmitter.EmitNewLine();
        break;
      }

      if (typeMayAlreadyBeInitialized) {
        this.sourceEmitter.EmitBlockClosingDelimiter("}");
        this.sourceEmitter.EmitNewLine();
      }

    }
Пример #12
0
    private void EmitExceptionSwitchTable(IEnumerable<IOperationExceptionInformation> operationExceptionInformation) {
      Contract.Requires(operationExceptionInformation != null);

      SetOfUints tryBlockOffsets = new SetOfUints();
      foreach (var expInfo in operationExceptionInformation) {
        Contract.Assume(expInfo != null);
        if (!tryBlockOffsets.Contains(expInfo.TryStartOffset+1)) {
          this.sourceEmitter.EmitLabel("lexpSwitch" + expInfo.TryStartOffset + ":");
          this.sourceEmitter.EmitNewLine();
          this.sourceEmitter.EmitString("switch (expSwitchVal" + expInfo.TryStartOffset + ") ");
          this.sourceEmitter.EmitBlockOpeningDelimiter("{");
          this.sourceEmitter.EmitNewLine();
          int val = 0;
          foreach (string label in this.exceptionSwitchTables.GetValuesFor(expInfo.TryStartOffset)) {
            Contract.Assert(label != null);
            this.sourceEmitter.EmitString("case " + val + " :");
            this.sourceEmitter.EmitNewLine();
            this.sourceEmitter.EmitString("goto " + label + ";");
            this.sourceEmitter.EmitNewLine();
            val++;
          }
          this.sourceEmitter.EmitBlockClosingDelimiter("}");
          this.sourceEmitter.EmitNewLine();
          this.sourceEmitter.EmitString("return 0; //dummy return to suppress warning");
          this.sourceEmitter.EmitNewLine();
          tryBlockOffsets.Add(expInfo.TryStartOffset+1);
        }
      }
      this.exceptionSwitchTables.Clear();
    }
Пример #13
0
    private void EmitExceptionSwitchTableDefinitions(IEnumerable<IOperationExceptionInformation> operationExceptionInformation) {
      Contract.Requires(operationExceptionInformation != null);

      bool haveCatchClauses = false;
      SetOfUints tryBlockOffsets = new SetOfUints();
      List<IOperationExceptionInformation> finallyHandlers = new List<IOperationExceptionInformation>();
      foreach (var expInfo in operationExceptionInformation) {
        Contract.Assume(expInfo != null);
        if (expInfo.HandlerKind == HandlerKind.Finally) {
          finallyHandlers.Add(expInfo);
        }else if (expInfo.HandlerKind == HandlerKind.Catch) {
          haveCatchClauses = true;
          this.catchHandlerOffsets.Add(expInfo.HandlerStartOffset+1);
          // Keep track of the finally handlers a catch handler MAY have to run in the event of a throw
          foreach (IOperationExceptionInformation finallyHandler in finallyHandlers) {
            Contract.Assume(finallyHandler != null);
            if (finallyHandler.HandlerEndOffset < expInfo.TryEndOffset && finallyHandler.HandlerStartOffset > expInfo.TryStartOffset) {
              this.finallyHandlersForCatch.Add((uint)expInfo.HandlerStartOffset, finallyHandler);
            }
          }
        }
        if (!tryBlockOffsets.Contains(expInfo.TryStartOffset+1)) {
          this.sourceEmitter.EmitString("int32_t expSwitchVal" + expInfo.TryStartOffset + ";");
          this.sourceEmitter.EmitNewLine();
          tryBlockOffsets.Add(expInfo.TryStartOffset+1);          
        }
      }
      if (haveCatchClauses) {
        this.sourceEmitter.EmitNewLine();
        this.sourceEmitter.EmitString("uint32_t canHandleExp = 0;");
      }
      this.sourceEmitter.EmitNewLine();
    }