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