public bool Create(Compiler compiler) { HighTypeDef typeDef = m_typeDef; foreach (TypeSpecClassTag ii in typeDef.ParentInterfaces) { if (!compiler.HaveCliOpenInterface(ii.TypeName)) return false; } Dictionary<TypeSpecClassTag, int> uniqueDeps = new Dictionary<TypeSpecClassTag, int>(); foreach (TypeSpecClassTag pi in typeDef.ParentInterfaces) { CliInterface ifc = compiler.GetClosedInterface(pi); if (!ifc.IsCreated) { ifc = compiler.GetClosedInterface(pi); throw new Exception(); } foreach (TypeSpecClassTag pipi in ifc.InterfaceImpls2) AddUniqueInterface(uniqueDeps, pipi); AddUniqueInterface(uniqueDeps, pi); } m_interfaceImpls = UnrollUniqueInterfaces(uniqueDeps); m_parentInterfaces = typeDef.ParentInterfaces; m_slots = typeDef.NewSlots; m_slotTagToCliSlot = new Dictionary<MethodDeclTag, uint>(); m_slotTagToRealSlot = new Dictionary<MethodDeclTag, uint>(); uint numGenericParameters = typeDef.NumGenericParameters; TypeSpecTag[] genericParameters = new TypeSpecTag[numGenericParameters]; for (uint i = 0; i < numGenericParameters; i++) { TypeSpecGenericParamTypeTag paramType = new TypeSpecGenericParamTypeTag(TypeSpecGenericParamTypeTag.Values.Var); TypeSpecTag paramTag = new TypeSpecGenericParamTag(paramType, i); paramTag = compiler.TagRepository.InternTypeSpec(paramTag); genericParameters[i] = paramTag; } m_numRealSlots = 0; uint cliSlot = 0; foreach (HighClassVtableSlot slot in m_slots) { if (m_slotTagToCliSlot.ContainsKey(slot.SlotTag)) throw new Exception("Duplicate interface vtable slot"); m_slotTagToCliSlot.Add(slot.SlotTag, cliSlot++); if (slot.Signature.NumGenericParameters > 0) m_slotTagToRealSlot.Add(slot.SlotTag, m_numRealSlots); } m_typeSpec = new TypeSpecClassTag(m_typeDef.TypeName, genericParameters); m_typeSpec = (TypeSpecClassTag)compiler.TagRepository.InternTypeSpec(m_typeSpec); m_isCreated = true; return true; }
private CliInterfaceImpl ResolveInterfaceImpl(Compiler compiler, HighInterfaceImplementation highIfcImpl) { CliInterface ifc = compiler.GetClosedInterface(highIfcImpl.Interface); CliInterfaceImplSlot[] slots = new CliInterfaceImplSlot[ifc.Slots.Length]; foreach (HighInterfaceMethodImplementation methodImpl in highIfcImpl.MethodImpls) { uint classIndex; if (!m_declTagToVTableSlot.TryGetValue(methodImpl.ClassSlot, out classIndex)) throw new Exception("Couldn't map class vtable slot to interface slot"); uint ifcIndex = ifc.CliSlotForSlotTag(methodImpl.InterfaceSlot); if (slots[ifcIndex].HaveNewImpl) throw new Exception("Interface method implemented multiple times"); slots[ifcIndex] = new CliInterfaceImplSlot(true, classIndex); } return new CliInterfaceImpl(highIfcImpl.Interface, slots.ToArray()); }