public override object GetResult(ISimAdapter simAdapter, MosaType type) { var x86 = simAdapter.SimCPU as CPUx86; if (type.IsI1) return (object)(sbyte)x86.EAX.Value; else if (type.IsI2) return (object)(short)x86.EAX.Value; else if (type.IsI4) return (object)(int)x86.EAX.Value; else if (type.IsI8) return (object)(long)(((ulong)x86.EAX.Value) | ((ulong)x86.EDX.Value << 32)); else if (type.IsU1) return (object)(byte)x86.EAX.Value; else if (type.IsU2) return (object)(ushort)x86.EAX.Value; else if (type.IsU4) return (object)(uint)x86.EAX.Value; else if (type.IsU8) return (object)(ulong)(((ulong)x86.EAX.Value) | ((ulong)x86.EDX.Value << 32)); else if (type.IsChar) return (object)(char)x86.EAX.Value; else if (type.IsBoolean) return (object)(bool)(x86.EAX.Value != 0); else if (type.IsR4) return (object)(float)x86.XMM0.Value.LowF; else if (type.IsR8) return (object)(double)x86.XMM0.Value.Low; else if (type.IsVoid) return null; return null; }
public CompilerTypeData(MosaType mosaType) { if (mosaType == null) throw new ArgumentNullException("mosaType"); MosaType = mosaType; }
public static object GetResult(MosaType type, List<byte> data) { if (type.IsI1) return (sbyte)data[0]; else if (type.IsI2) return (short)(data[0] | (data[1] << 8)); else if (type.IsI4) return (int)(data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24)); else if (type.IsI8) { ulong low = (uint)(data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24)); ulong high = (uint)(data[4] | (data[5] << 8) | (data[6] << 16) | (data[7] << 24)); return (long)(low | (high << 32)); } else if (type.IsU1) return (byte)data[0]; else if (type.IsU2) return (ushort)(data[0] | (data[1] << 8)); else if (type.IsU4) return (uint)(data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24)); else if (type.IsU8) { ulong low = (uint)(data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24)); ulong high = (uint)(data[4] | (data[5] << 8) | (data[6] << 16) | (data[7] << 24)); return (ulong)(low | (high << 32)); } else if (type.IsChar) return (char)(data[0] | (data[1] << 8)); else if (type.IsBoolean) return (bool)(data[0] != 0); else if (type.IsR4) { var value = new byte[8]; for (int i = 0; i < 8; i++) value[i] = data[i]; var d = BitConverter.ToSingle(value, 0); return d; } else if (type.IsR8) { var value = new byte[8]; for (int i = 0; i < 8; i++) value[i] = data[i]; var d = BitConverter.ToDouble(value, 0); return d; } else if (type.IsVoid) return null; return null; }
private string GetTypeDefinition(MosaType allocatedType) { if (!allocatedType.IsValueType) { return allocatedType.FullName + Metadata.TypeDefinition; } return null; }
protected override void Run() { exceptionType = TypeSystem.GetTypeByName("System", "Exception"); InsertBlockProtectInstructions(); UpdateBlockProtectInstructions(); MethodCompiler.SetProtectedRegions(ProtectedRegion.CreateProtectedRegions(BasicBlocks, MethodCompiler.Method.ExceptionHandlers)); }
private string GetMethodTableForType(MosaType allocatedType) { if (!allocatedType.IsValueType) { return allocatedType.FullName + @"$mtable"; } return null; }
private Operand InsertLoadBeforeInstruction(Context context, string symbolName, MosaType type) { var before = context.InsertBefore(); Operand result = MethodCompiler.CreateVirtualRegister(type); Operand op = Operand.CreateManagedSymbol(type, symbolName); before.SetInstruction(CILInstruction.Get(OpCode.Ldc_i4), result, op); return result; }
private static MosaField GetField(MosaType type, string name) { foreach (var field in type.Fields) { if (field.Name == name) return field; } return GetField(type.BaseType, name); }
private void AllocateStaticFields(MosaType type) { foreach (var field in type.Fields) { // TODO: Inline literal field constants if (field.IsStatic) { // Assign a memory slot to the static & initialize it, if there's initial data set CreateStaticField(field); } } }
private int ComputeArgumentSize(MosaType type, object value) { if (type.IsEnum) type = type.GetEnumUnderlyingType(); switch (type.TypeCode) { // 1 byte case MosaTypeCode.Boolean: case MosaTypeCode.U1: case MosaTypeCode.I1: return 1; // 2 bytes case MosaTypeCode.Char: case MosaTypeCode.U2: case MosaTypeCode.I2: return 2; // 4 bytes case MosaTypeCode.U4: case MosaTypeCode.I4: case MosaTypeCode.R4: return 4; // 8 bytes case MosaTypeCode.U8: case MosaTypeCode.I8: case MosaTypeCode.R8: return 8; // SZArray case MosaTypeCode.SZArray: Debug.Assert(value is MosaCustomAttribute.Argument[]); var arr = (MosaCustomAttribute.Argument[])value; int size = 0; foreach (var elem in arr) size += ComputeArgumentSize(elem.Type, elem.Value); return size; // String case MosaTypeCode.String: return TypeLayout.NativePointerSize; default: if (type.FullName == "System.Type") { return TypeLayout.NativePointerSize; } else throw new NotSupportedException(); } }
public MosaExceptionHandler(ExceptionHandlerType ehType, int tryStart, int tryEnd, int handlerStart, int handlerEnd, MosaType type, int? filterOffset) { HandlerType = ehType; TryStart = tryStart; TryEnd = tryEnd; HandlerStart = handlerStart; HandlerEnd = handlerEnd; Type = type; FilterOffset = filterOffset; }
public static void UpdateType(MosaType type) { StringBuilder result = new StringBuilder(); if (type.ElementType != null) { result.Append(type.ElementType.Signature); } if (type.GenericArguments.Count > 0) { result.Append("<"); for (int i = 0; i < type.GenericArguments.Count; i++) { if (i != 0) result.Append(", "); result.Append(type.GenericArguments[i].FullName); } result.Append(">"); } switch (type.TypeCode) { case MosaTypeCode.UnmanagedPointer: result.Append("*"); break; case MosaTypeCode.ManagedPointer: result.Append("&"); break; case MosaTypeCode.SZArray: case MosaTypeCode.Array: result.Append(type.ArrayInfo.ToString()); break; case MosaTypeCode.FunctionPointer: result.Append(type.FunctionPtrSig.ToString()); break; default: break; } if (type.Modifier != null) { result.Append(" mod("); result.Append(type.Modifier.Name); result.Append(")"); } type.Signature = result.ToString(); }
public CompilerTypeData GetCompilerTypeData(MosaType type) { lock (compilerTypes) { CompilerTypeData compilerType; if (!compilerTypes.TryGetValue(type, out compilerType)) { compilerType = new CompilerTypeData(type); compilerTypes.Add(type, compilerType); } return compilerType; } }
public void Schedule(MosaType type) { if (type.IsModule) return; if (type.IsInterface) return; if (type.HasOpenGenericParams || type.IsPointer) return; foreach (var method in type.Methods) { Schedule(method); } }
private void CreateFieldDefinitions(MosaType type) { foreach (MosaField field in type.Fields) { string fieldNameSymbol = field.FullName + @"$name"; // Emit field name using (Stream stream = Linker.Allocate(fieldNameSymbol, SectionKind.ROData, 0, TypeLayout.NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness)) { EmitStringWithLength(writer, field.Name); } } string fieldDescSymbol = field.FullName + @"$desc"; // Emit field descriptor using (Stream stream = Linker.Allocate(fieldDescSymbol, SectionKind.ROData, 0, TypeLayout.NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness)) { // 1. Offset / Address if (field.IsStatic && !field.IsLiteral) { Linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, fieldDescSymbol, (int)writer.Position, 0, field.FullName, 0); } else { writer.Write(TypeLayout.GetFieldOffset(field)); writer.Position -= 4; } writer.Position += TypeLayout.NativePointerSize; // 2. Name Linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, fieldDescSymbol, (int)writer.Position, 0, fieldNameSymbol, 0); writer.Position += TypeLayout.NativePointerSize; // 3. Size writer.Write((uint)TypeLayout.GetFieldSize(field)); // 4. Metadata Token writer.Write((uint)0); //FIXME! } } } }
private static List<MosaType> GetInterfaces(MosaType type) { var interfaces = new List<MosaType>(); var baseType = type; while (baseType != null) { foreach (var interfaceType in baseType.Interfaces) { interfaces.AddIfNew(interfaceType); } baseType = baseType.BaseType; } return interfaces; }
private void CreateTypeDefinitionTable(MosaType type) { string typeNameSymbol = type + @"$tname"; // Emit type name using (Stream stream = Linker.Allocate(typeNameSymbol, SectionKind.ROData, 0, TypeLayout.NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness)) { EmitStringWithLength(writer, type.FullName); } } string typeTableSymbol = type.FullName + @"$dtable"; using (Stream stream = Linker.Allocate(typeTableSymbol, SectionKind.ROData, 0, TypeLayout.NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness)) { // 1. Size writer.Write((uint)TypeLayout.GetTypeSize(type)); // 2. Metadata Token //writer.Write((uint)type.Token.ToUInt32()); writer.Write((uint)0); //FIXME! ^^^ // 3. Pointer to Name Linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, typeTableSymbol, (int)writer.Position, 0, typeNameSymbol, 0); writer.Position += TypeLayout.NativePointerSize; // 4. Pointer to Assembly Definition //linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, typeTableSymbol, (int)writer.Position, 0, assemblySymbol, 0); writer.Position += TypeLayout.NativePointerSize; // 5. TODO: Constructor that accepts no parameters, if any, for this type writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 6. Flag: IsInterface writer.WriteByte((byte)(type.IsInterface ? 1 : 0)); } } CreateFieldDefinitions(type); }
protected override void Run() { exceptionType = TypeSystem.GetTypeByName("System", "Exception"); exceptionRegister = Operand.CreateCPURegister(exceptionType, Architecture.ExceptionRegister); leaveTargetRegister = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, Architecture.LeaveTargetRegister); nullOperand = Operand.GetNull(TypeSystem); // collect leave targets leaveTargets = CollectLeaveTargets(); var dispatches = new Dictionary<BaseInstruction, Dispatch>(); dispatches.Add(IRInstruction.Throw, ThrowInstruction); dispatches.Add(IRInstruction.FinallyStart, FinallyStartInstruction); dispatches.Add(IRInstruction.FinallyEnd, FinallyEndInstruction); dispatches.Add(IRInstruction.ExceptionStart, ExceptionStartInstruction); dispatches.Add(IRInstruction.SetLeaveTarget, SetLeaveTargetInstruction); dispatches.Add(IRInstruction.GotoLeaveTarget, GotoLeaveTargetInstruction); dispatches.Add(IRInstruction.Flow, Empty); dispatches.Add(IRInstruction.TryStart, Empty); dispatches.Add(IRInstruction.TryEnd, Empty); dispatches.Add(IRInstruction.ExceptionEnd, Empty); for (int i = 0; i < BasicBlocks.Count; i++) { for (var node = BasicBlocks[i].First; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) continue; Dispatch dispatch; if (dispatches.TryGetValue(node.Instruction, out dispatch)) { dispatch.Invoke(node); } } } }
private LinkerSymbol CreateProtectedRegionDefinition(string name, uint start, uint end, uint handler, ExceptionHandlerType handlerType, MosaType exceptionType) { // Emit parameter table var protectedRegionDefinitionSymbol = MethodCompiler.Linker.CreateSymbol(name, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer1 = new EndianAwareBinaryWriter(protectedRegionDefinitionSymbol.Stream, Architecture.Endianness); // 1. Offset to start writer1.Write(start, TypeLayout.NativePointerSize); // 2. Offset to end writer1.Write(end, TypeLayout.NativePointerSize); // 3. Offset to handler writer1.Write(handler, TypeLayout.NativePointerSize); // 4. Handler type writer1.Write((uint)handlerType, TypeLayout.NativePointerSize); // 5. Exception object type if (handlerType == ExceptionHandlerType.Exception) { // Store method table pointer of the exception object type // The VES exception runtime will uses this to compare exception object types MethodCompiler.Linker.Link(LinkType.AbsoluteAddress, NativePatchType, protectedRegionDefinitionSymbol, (int)writer1.Position, 0, exceptionType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0); } else if (handlerType == ExceptionHandlerType.Filter) { // TODO: There are no plans in the short term to support filtered exception clause as C# does not use them } else { } writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // Return protectedRegionSymbol for linker usage return protectedRegionDefinitionSymbol; }
private void CopyCompound(Context context, MosaType type, Operand destinationBase, Operand destination, Operand sourceBase, Operand source) { context.Empty(); Architecture.InsertCompoundCopy(MethodCompiler, context, destinationBase, destination, sourceBase, source, TypeLayout.GetTypeSize(type)); }
private LinkerSymbol CreateTypeDefinition(MosaType type, LinkerSymbol assemblyTableSymbol) { // Emit type table var typeNameSymbol = EmitStringWithLength(Metadata.NameString + type.FullName, type.FullName); var typeTableSymbol = Linker.DefineSymbol(Metadata.TypeDefinition + type.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer = new BinaryWriter(typeTableSymbol.Stream); // 1. Pointer to Name Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), typeNameSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 2. Pointer to Custom Attributes if (type.CustomAttributes.Count > 0) { var customAttributeListSymbol = CreateCustomAttributesTable(type); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), customAttributeListSymbol, 0); } writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 3. Type Code & Attributes writer.Write(((uint)type.TypeCode << 24) + (uint)type.TypeAttributes, TypeLayout.NativePointerSize); // 4. Size writer.Write((uint)TypeLayout.GetTypeSize(type), TypeLayout.NativePointerSize); // 5. Pointer to Assembly Definition Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), assemblyTableSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 6. Pointer to Base Type if (type.BaseType != null) { Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), Metadata.TypeDefinition + type.BaseType.FullName, 0); } writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 7. Pointer to Declaring Type if (type.DeclaringType != null) { Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), Metadata.TypeDefinition + type.DeclaringType.FullName, 0); } writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 8. Pointer to Element Type if (type.ElementType != null) { Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), Metadata.TypeDefinition + type.ElementType.FullName, 0); } writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 9. Constructor that accepts no parameters, if any, for this type foreach (var method in type.Methods) { if (!method.IsConstructor || method.Signature.Parameters.Count != 0 || method.HasOpenGenericParams) { continue; } var targetMethodData = GetTargetMethodData(method); if (targetMethodData.HasCode) { Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), Metadata.MethodDefinition + targetMethodData.Method.FullName, 0); } break; } writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 10. Properties (if any) if (type.Properties.Count > 0) { var propertiesSymbol = CreatePropertyDefinitions(type); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), propertiesSymbol, 0); } writer.WriteZeroBytes(TypeLayout.NativePointerSize); // If the type is not an interface continue, otherwise just pad until the end if (!type.IsInterface) { // 11. Fields (if any) if (type.Fields.Count > 0) { var fieldsSymbol = CreateFieldDefinitions(type); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), fieldsSymbol, 0); } writer.WriteZeroBytes(TypeLayout.NativePointerSize); var interfaces = type.HasOpenGenericParams ? null : GetInterfaces(type); // If the type doesn't use interfaces then skip 9 and 10 if (interfaces != null && interfaces.Count > 0) { // 12. Pointer to Interface Slots var interfaceSlotTableSymbol = CreateInterfaceSlotTable(type, interfaces); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), interfaceSlotTableSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 13. Pointer to Interface Bitmap var interfaceBitmapSymbol = CreateInterfaceBitmap(type, interfaces); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), interfaceBitmapSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); } else { // Fill 12 and 13 with zeros writer.WriteZeroBytes(TypeLayout.NativePointerSize * 2); } // For the next part we'll need to get the list of methods from the MosaTypeLayout var methodList = TypeLayout.GetMethodTable(type) ?? new List <MosaMethod>(); // 14. Number of Methods writer.Write(methodList.Count, TypeLayout.NativePointerSize); // 15. Pointer to Methods foreach (var method in methodList) { var targetMethodData = GetTargetMethodData(method); if (targetMethodData.HasCode) { Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), targetMethodData.Method.FullName, 0); } writer.WriteZeroBytes(TypeLayout.NativePointerSize); } // 16. Pointer to Method Definitions foreach (var method in methodList) { // Create definition and get the symbol var methodDefinitionSymbol = CreateMethodDefinition(method); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.GetPosition(), methodDefinitionSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); } } else { // Fill 11, 12, 13, 14 with zeros, 15 & 16 can be left out. writer.WriteZeroBytes(TypeLayout.NativePointerSize * 4); } return(typeTableSymbol); }
public BaseIRInstruction GetLoadParameterInstruction(MosaType type) { return(GetLoadParameterInstruction(type, Is32BitPlatform)); }
/// <summary> /// Allocates the virtual register or stack slot. /// </summary> /// <param name="type">The type.</param> /// <returns></returns> public Operand AllocateVirtualRegisterOrStackSlot(MosaType type) { return(MethodCompiler.AllocateVirtualRegisterOrStackSlot(type)); }
/// <summary> /// Gets the size of the type. /// </summary> /// <param name="type">The type.</param> /// <param name="align">if set to <c>true</c> [align].</param> /// <returns></returns> public int GetTypeSize(MosaType type, bool align) { return(MethodCompiler.GetReferenceOrTypeSize(type, align)); }
public static TypeSig GetTypeSig(this MosaType type) { return(type.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Signature); }
/// <summary> /// Creates a new memory address <see cref="Operand" />. /// </summary> /// <param name="type">The type.</param> /// <param name="offsetBase">The base register.</param> /// <param name="offset">The offset.</param> /// <returns></returns> public static Operand CreateMemoryAddress(MosaType type, Operand offsetBase, long offset) { var operand = new Operand(type); operand.IsMemoryAddress = true; operand.OffsetBase = offsetBase; operand.Displacement = offset; return operand; }
private void WriteArgument(BinaryWriter writer, LinkerSymbol symbol, MosaType type, object value) { if (type.IsEnum) { type = type.GetEnumUnderlyingType(); } switch (type.TypeCode) { // 1 byte case MosaTypeCode.Boolean: writer.Write((bool)value); break; case MosaTypeCode.U1: writer.Write((byte)value); break; case MosaTypeCode.I1: writer.Write((sbyte)value); break; // 2 bytes case MosaTypeCode.Char: writer.Write((char)value); break; case MosaTypeCode.U2: writer.Write((ushort)value); break; case MosaTypeCode.I2: writer.Write((short)value); break; // 4 bytes case MosaTypeCode.U4: writer.Write((uint)value); break; case MosaTypeCode.I4: writer.Write((int)value); break; case MosaTypeCode.R4: writer.Write((float)value); break; // 8 bytes case MosaTypeCode.U8: writer.Write((ulong)value); break; case MosaTypeCode.I8: writer.Write((long)value); break; case MosaTypeCode.R8: writer.Write((double)value); break; // SZArray case MosaTypeCode.SZArray: Debug.Assert(value is MosaCustomAttribute.Argument[]); var arr = (MosaCustomAttribute.Argument[])value; writer.Write(arr.Length, TypeLayout.NativePointerSize); foreach (var elem in arr) { WriteArgument(writer, symbol, elem.Type, elem.Value); } break; // String case MosaTypeCode.String: // Since strings are immutable, make it an object that we can just use var str = (string)value; Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, writer.GetPosition(), $"{Metadata.TypeDefinition}System.String", 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize * 2); writer.Write(str.Length, TypeLayout.NativePointerSize); writer.Write(Encoding.Unicode.GetBytes(str)); break; default: if (type.FullName == "System.Type") { var valueType = (MosaType)value; Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, writer.GetPosition(), Metadata.TypeDefinition + valueType.FullName, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); } else { throw new NotSupportedException(); } break; } }
/// <summary> /// Creates a new constant <see cref="Operand" /> for the given integral value. /// </summary> /// <param name="type">The type.</param> /// <param name="value">The value to create the constant operand for.</param> /// <returns> /// A new operand representing the value <paramref name="value" />. /// </returns> public static Operand CreateConstant(MosaType type, int value) { return CreateConstant(type, (long)value); }
/// <summary> /// Creates a new symbol <see cref="Operand" /> for the given symbol name. /// </summary> /// <param name="type">The type.</param> /// <param name="label">The label.</param> /// <returns></returns> public static Operand CreateLabel(MosaType type, string label) { var operand = new Operand(type); operand.IsMemoryAddress = true; operand.IsLabel = true; operand.Name = label; operand.Displacement = 0; return operand; }
protected override void Initialize() { exceptionType = TypeSystem.GetTypeByName("System", "Exception"); }
private bool HasInterface(MosaType type) { return(CheckBaseTypesForInterface(type) || CheckDerivedTypesForInterface(type)); }
protected string FormatMosaType(MosaType type) { return(type.Namespace + Type.Delimiter + type.Name); }
private LinkerSymbol CreateFieldDefinitions(MosaType type) { // Emit fields table var fieldsTableSymbol = Linker.DefineSymbol(Metadata.FieldsTable + type.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer1 = new BinaryWriter(fieldsTableSymbol.Stream); // 1. Number of Fields writer1.Write((uint)type.Fields.Count, TypeLayout.NativePointerSize); // 2. Pointers to Field Definitions foreach (var field in type.Fields) { // Emit field name var fieldNameSymbol = EmitStringWithLength(Metadata.NameString + field.FullName, field.Name); // Emit field definition var fieldDefSymbol = Linker.DefineSymbol(Metadata.FieldDefinition + field.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer2 = new BinaryWriter(fieldDefSymbol.Stream); // 1. Name Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.GetPosition(), fieldNameSymbol, 0); writer2.WriteZeroBytes(TypeLayout.NativePointerSize); // 2. Pointer to Custom Attributes if (field.CustomAttributes.Count > 0) { var customAttributesTableSymbol = CreateCustomAttributesTable(field); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.GetPosition(), customAttributesTableSymbol, 0); } writer2.WriteZeroBytes(TypeLayout.NativePointerSize); // 3. Attributes writer2.Write((uint)field.FieldAttributes, TypeLayout.NativePointerSize); // 4. Pointer to Field Type Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.GetPosition(), Metadata.TypeDefinition + field.FieldType.FullName, 0); writer2.WriteZeroBytes(TypeLayout.NativePointerSize); // 5 & 6. Offset / Address + Size if (field.IsStatic && !field.IsLiteral && !type.HasOpenGenericParams) { if (Compiler.MethodScanner.IsFieldAccessed(field)) { Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.GetPosition(), field.FullName, 0); } writer2.WriteZeroBytes(TypeLayout.NativePointerSize); writer2.Write(field.Data?.Length ?? 0, TypeLayout.NativePointerSize); } else { writer2.WriteZeroBytes(TypeLayout.NativePointerSize); writer2.Write(TypeLayout.GetFieldOffset(field), TypeLayout.NativePointerSize); } // Add pointer to field list Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldsTableSymbol, writer1.GetPosition(), fieldDefSymbol, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); } return(fieldsTableSymbol); }
protected string FormatMosaType(MosaType type) { return type.Namespace + Type.Delimiter + type.Name; }
private LinkerSymbol CreatePropertyDefinitions(MosaType type) { // Emit properties table var propertiesTableSymbol = Linker.DefineSymbol(Metadata.PropertiesTable + type.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer = new BinaryWriter(propertiesTableSymbol.Stream); // 1. Number of Properties writer.Write((uint)type.Properties.Count, TypeLayout.NativePointerSize); // 2. Pointers to Property Definitions foreach (var property in type.Properties) { // Emit field name var fieldNameSymbol = EmitStringWithLength(Metadata.NameString + property.FullName, property.Name); // Emit property definition var propertyDefSymbol = Linker.DefineSymbol(Metadata.PropertyDefinition + property.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer2 = new BinaryWriter(propertyDefSymbol.Stream); // 1. Name Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertyDefSymbol, writer2.GetPosition(), fieldNameSymbol, 0); writer2.WriteZeroBytes(TypeLayout.NativePointerSize); // 2. Pointer to Custom Attributes if (property.CustomAttributes.Count > 0) { var customAttributesTableSymbol = CreateCustomAttributesTable(property); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertyDefSymbol, writer.GetPosition(), customAttributesTableSymbol, 0); } writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 3. Attributes writer.Write((uint)property.PropertyAttributes, TypeLayout.NativePointerSize); // 4. Pointer to Property Type Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertyDefSymbol, writer2.GetPosition(), Metadata.TypeDefinition + property.PropertyType.FullName, 0); writer2.WriteZeroBytes(TypeLayout.NativePointerSize); // If the type is a interface then skip linking the methods if (!type.IsInterface) { // TODO: Replace .HasImpelement with .HasCode // 5. Pointer to Getter Method Definition if (property.GetterMethod != null && property.GetterMethod.HasImplementation && !property.GetterMethod.HasOpenGenericParams) { Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertyDefSymbol, writer2.GetPosition(), Metadata.MethodDefinition + property.GetterMethod.FullName, 0); } writer2.WriteZeroBytes(TypeLayout.NativePointerSize); // 6. Pointer to Setter Method Definition if (property.SetterMethod != null && property.SetterMethod.HasImplementation && !property.SetterMethod.HasOpenGenericParams) { Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertyDefSymbol, writer2.GetPosition(), Metadata.MethodDefinition + property.SetterMethod.FullName, 0); } writer2.WriteZeroBytes(TypeLayout.NativePointerSize); } else { // Fill 5 and 6 with zeros. writer.WriteZeroBytes(TypeLayout.NativePointerSize * 2); } // Add pointer to properties table Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertiesTableSymbol, writer.GetPosition(), propertyDefSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); } return(propertiesTableSymbol); }
/// <summary> /// Adds the stack local. /// </summary> /// <param name="type">The type.</param> /// <returns></returns> public Operand AddStackLocal(MosaType type) { return(AddStackLocal(type, false)); }
protected static Operand CreateConstant(MosaType type, long value) { return(Operand.CreateConstant(type, (ulong)value)); }
public static Operand Create(MosaType type, long value) { return(Operand.CreateConstant(type, (ulong)value)); }
public void AddType(MosaType type) { typeLookup.Add(type.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Token, type); }
protected BaseInstruction GetLoadInstruction(MosaType type) { if (type.IsPointer || type.IsReferenceType) { return(Select(IRInstruction.LoadInt32, IRInstruction.LoadInt64)); } if (type.IsPointer) { return(Select(IRInstruction.LoadInt32, IRInstruction.LoadInt64)); } else if (type.IsI1) { return(Select(IRInstruction.LoadSignExtend8x32, IRInstruction.LoadSignExtend8x64)); } else if (type.IsI2) { return(Select(IRInstruction.LoadSignExtend16x32, IRInstruction.LoadSignExtend16x64)); } else if (type.IsI4) { return(Select(IRInstruction.LoadInt32, IRInstruction.LoadSignExtend32x64)); } else if (type.IsI8) { return(IRInstruction.LoadInt64); } else if (type.IsU1 || type.IsBoolean) { return(Select(IRInstruction.LoadZeroExtend8x32, IRInstruction.LoadZeroExtend8x64)); } else if (type.IsU2 || type.IsChar) { return(Select(IRInstruction.LoadZeroExtend16x32, IRInstruction.LoadZeroExtend16x64)); } else if (type.IsU4) { return(Select(IRInstruction.LoadInt32, IRInstruction.LoadZeroExtend32x64)); } else if (type.IsU8) { return(IRInstruction.LoadInt64); } else if (type.IsR4) { return(IRInstruction.LoadFloatR4); } else if (type.IsR8) { return(IRInstruction.LoadFloatR8); } else if (Is32BitPlatform) // review { return(IRInstruction.LoadInt32); } else if (Is64BitPlatform) { return(IRInstruction.LoadInt64); } throw new InvalidOperationException(); }
public void EnqueueForArrayResolve(MosaType type) { arrayResolveQueue.Enqueue(type); }
protected BaseIRInstruction GetStoreParameterInstruction(MosaType type) { return(GetStoreParameterInstruction(type, Is32BitPlatform)); }
public static Operand Create(MosaType type, uint value) { return(Operand.CreateConstant(type, value)); }
protected static Operand CreateConstant(MosaType type, uint value) { return(Operand.CreateConstant(type, value)); }
public void TrackTypeAllocated(MosaType type) { }
/// <summary> /// Creates a new virtual register operand. /// </summary> /// <param name="type">The signature type of the virtual register.</param> /// <returns> /// An operand, which represents the virtual register. /// </returns> public Operand CreateVirtualRegister(MosaType type) { return(VirtualRegisters.Allocate(type)); }
private int CalculateInterfaceSlot(MosaType interaceType) { return(TypeLayout.GetInterfaceSlot(interaceType)); }
/// <summary> /// Allocates the virtual register. /// </summary> /// <param name="type">The type.</param> /// <returns></returns> protected Operand AllocateVirtualRegister(MosaType type) { return(MethodCompiler.VirtualRegisters.Allocate(type)); }
/// <summary> /// Creates a new physical register <see cref="Operand" />. /// </summary> /// <param name="type">The type.</param> /// <param name="register">The register.</param> /// <returns></returns> public static Operand CreateCPURegister(MosaType type, Register register) { var operand = new Operand(type); operand.IsCPURegister = true; operand.Register = register; return operand; }
private LinkerSymbol CreateProtectedRegionDefinition(string name, uint start, uint end, uint handler, ExceptionHandlerType handlerType, MosaType exceptionType) { // Emit parameter table var protectedRegionDefinitionSymbol = MethodCompiler.Linker.CreateSymbol(name, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer1 = new EndianAwareBinaryWriter(protectedRegionDefinitionSymbol.Stream, Architecture.Endianness); // 1. Offset to start writer1.Write(start, TypeLayout.NativePointerSize); // 2. Offset to end writer1.Write(end, TypeLayout.NativePointerSize); // 3. Offset to handler writer1.Write(handler, TypeLayout.NativePointerSize); // 4. Handler type writer1.Write((uint)handlerType, TypeLayout.NativePointerSize); // 5. Exception object type if (handlerType == ExceptionHandlerType.Exception) { // Store method table pointer of the exception object type // The VES exception runtime will uses this to compare exception object types MethodCompiler.Linker.Link(LinkType.AbsoluteAddress, NativePatchType, protectedRegionDefinitionSymbol, (int)writer1.Position, SectionKind.ROData, exceptionType.FullName + Metadata.TypeDefinition, 0); } else if (handlerType == ExceptionHandlerType.Filter) { // TODO: There are no plans in the short term to support filtered exception clause as C# does not use them } else { } writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // Return protectedRegionSymbol for linker usage return(protectedRegionDefinitionSymbol); }
/// <summary> /// Creates the symbol. /// </summary> /// <param name="type">The type.</param> /// <param name="name">The name.</param> /// <returns></returns> public static Operand CreateManagedSymbol(MosaType type, string name) { var operand = new Operand(type); operand.IsSymbol = true; operand.Name = name; return operand; }
public StackTypeCode GetStackTypeCode(MosaType type) { switch (type.IsEnum ? type.GetEnumUnderlyingType().TypeCode : type.TypeCode) { case MosaTypeCode.Boolean: case MosaTypeCode.Char: case MosaTypeCode.I1: case MosaTypeCode.U1: case MosaTypeCode.I2: case MosaTypeCode.U2: case MosaTypeCode.I4: case MosaTypeCode.U4: if (Architecture.Is32BitPlatform) { return(StackTypeCode.Int32); } else { return(StackTypeCode.Int64); } case MosaTypeCode.I8: case MosaTypeCode.U8: return(StackTypeCode.Int64); case MosaTypeCode.R4: case MosaTypeCode.R8: return(StackTypeCode.F); case MosaTypeCode.I: case MosaTypeCode.U: if (Architecture.Is32BitPlatform) { return(StackTypeCode.Int32); } else { return(StackTypeCode.Int64); } case MosaTypeCode.ManagedPointer: return(StackTypeCode.ManagedPointer); case MosaTypeCode.UnmanagedPointer: case MosaTypeCode.FunctionPointer: return(StackTypeCode.UnmanagedPointer); case MosaTypeCode.String: case MosaTypeCode.ValueType: case MosaTypeCode.ReferenceType: case MosaTypeCode.Array: case MosaTypeCode.Object: case MosaTypeCode.SZArray: case MosaTypeCode.Var: case MosaTypeCode.MVar: return(StackTypeCode.O); case MosaTypeCode.Void: return(StackTypeCode.Unknown); } throw new CompilerException($"Can't transform Type {type} to StackTypeCode"); }
/// <summary> /// Creates a new local variable <see cref="Operand" />. /// </summary> /// <param name="type">The type.</param> /// <param name="register">The register.</param> /// <param name="displacement">The displacement.</param> /// <param name="index">The index.</param> /// <returns></returns> public static Operand CreateParameter(MosaType type, Register register, int displacement, int index, string name) { var operand = new Operand(type); operand.IsMemoryAddress = true; operand.IsParameter = true; operand.Register = register; operand.Index = index; operand.Displacement = displacement; operand.Name = name; return operand; }
/// <summary> /// Allocates the virtual register. /// </summary> /// <param name="type">The type.</param> /// <returns></returns> public Operand Allocate(MosaType type) { return(Allocate(type, null)); }
private void ResolveInterfacesInBaseTypes(MosaType.Mutator mosaType, MosaType baseType) { foreach (MosaType iface in baseType.Interfaces) { if (mosaType.Interfaces.Contains(iface)) continue; mosaType.Interfaces.Add(iface); } if (baseType.BaseType != null) ResolveInterfacesInBaseTypes(mosaType, baseType.BaseType); }
private Operand InsertLoadBeforeInstruction(Context context, string symbolName, MosaType type) { var before = context.InsertBefore(); Operand result = MethodCompiler.CreateVirtualRegister(type); Operand op = Operand.CreateManagedSymbol(type, symbolName); before.SetInstruction(CILInstruction.Get(OpCode.Ldc_i4), result, op); return(result); }
private void ResolveType(MosaType type) { GenericArgumentResolver resolver = new GenericArgumentResolver(); MosaType srcType = type; if (type.GenericArguments.Count > 0) { resolver.PushTypeGenericArguments(type.GenericArguments.GetGenericArguments()); srcType = type.ElementType; Debug.Assert(srcType != null); } using (var mosaType = metadata.Controller.MutateType(type)) { if (srcType.BaseType != null) mosaType.BaseType = metadata.Loader.GetType(resolver.Resolve(srcType.BaseType.GetTypeSig())); if (srcType.DeclaringType != null) { mosaType.DeclaringType = metadata.Loader.GetType(resolver.Resolve(srcType.DeclaringType.GetTypeSig())); mosaType.Namespace = srcType.DeclaringType.Namespace; } var ifaces = new List<MosaType>(srcType.Interfaces); mosaType.Interfaces.Clear(); for (int i = 0; i < ifaces.Count; i++) mosaType.Interfaces.Add(metadata.Loader.GetType(resolver.Resolve(ifaces[i].GetTypeSig()))); mosaType.HasOpenGenericParams = type.GetTypeSig().HasOpenGenericParameter(); ResolveCustomAttributes(mosaType, srcType.GetUnderlyingObject<UnitDesc<TypeDef, TypeSig>>().Definition); } // Add type again to make it easier to find metadata.Controller.AddType(type); }
/// <summary> /// Initializes a new instance of <see cref="Operand"/>. /// </summary> /// <param name="type">The type of the operand.</param> private Operand(MosaType type) : this() { Debug.Assert(type != null); Type = type; }
public void TrackTypeAllocated(MosaType type) { }
/// <summary> /// Creates a new constant <see cref="Operand" /> for the given integral value. /// </summary> /// <param name="type">The type.</param> /// <param name="value">The value to create the constant operand for.</param> /// <returns> /// A new operand representing the value <paramref name="value" />. /// </returns> public static Operand CreateConstant(MosaType type, int value) { return(CreateConstant(type, (long)value)); }