private LinkerSymbol CreateInterfaceMethodTable(MosaType type, MosaType interfaceType) { // Emit interface method table var interfaceMethodTableSymbol = Linker.DefineSymbol(Metadata.InterfaceMethodTable + type.FullName + "$" + interfaceType.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer = new EndianAwareBinaryWriter(interfaceMethodTableSymbol.Stream, Architecture.Endianness); var interfaceMethodTable = TypeLayout.GetInterfaceTable(type, interfaceType) ?? new MosaMethod[0]; // 1. Number of Interface Methods writer.Write((uint)interfaceMethodTable.Length, TypeLayout.NativePointerSize); // 2. Pointer to Interface Type Linker.Link(LinkType.AbsoluteAddress, NativePatchType, interfaceMethodTableSymbol, writer.Position, Metadata.TypeDefinition + interfaceType.FullName, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 3. Pointers to Method Definitions foreach (var method in interfaceMethodTable) { // Create definition and get the symbol var methodDefinitionSymbol = CreateMethodDefinition(method); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, interfaceMethodTableSymbol, writer.Position, methodDefinitionSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); } return(interfaceMethodTableSymbol); }
private void ScheduleInterfaces(MosaType type) { if (type.Interfaces.Count == 0) { return; } // find all interfaces methods for this type foreach (var itype in type.Interfaces) { if (!invokedInteraceTypes.Contains(itype)) { continue; } var imethods = TypeLayout.GetInterfaceTable(type, itype); var list = interfaceSlots.Get(itype); foreach (var slot in list) { var imethod = imethods[slot]; ScheduleMethod(imethod); } } }
private bool IsInterfaceMethod() { foreach (var iface in MethodCompiler.Type.Interfaces) { foreach (var method in TypeLayout.GetInterfaceTable(MethodCompiler.Type, iface)) { if (method == MethodCompiler.Method) return true; } } return false; }
public void InterfaceMethodInvoked(MosaMethod method, MosaMethod source) { if (!IsEnabled) { return; } MarkMethodInvoked(method); if (trace != null) { lock (trace) { if ((lastSource == null && source != null) || (lastSource != source)) { trace.Log($"> Method: {(source == null ? "[NONE]" : source.FullName)}"); lastSource = source; } trace.Log($" >> Invoked: {method.FullName}{(method.IsStatic ? " [Static]" : " [Virtual]")}"); } } lock (_lock) { invokedInteraceTypes.Add(method.DeclaringType); int slot = TypeLayout.GetMethodSlot(method); var interfaceType = method.DeclaringType; interfaceSlots.AddIfNew(interfaceType, slot); // For every allocated type that implements this interface method, schedule the type's interface method foreach (var type in TypeSystem.AllTypes) { if (type.IsInterface) { continue; } if (!type.Interfaces.Contains(interfaceType)) { continue; } lock (allocatedTypes) { if (!allocatedTypes.Contains(type)) { continue; } } var imethods = TypeLayout.GetInterfaceTable(type, interfaceType); // this can be slow var imethod = imethods[slot]; // schedule this type's interface method implementation ScheduleMethod(imethod); } } }