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); } } }
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); }
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(); }
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(); }
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++; } }
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); } } } } } }
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); } }
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); } } }
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(); }
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; }
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(); } }
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(); }
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(); }