Пример #1
0
        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;
        }
Пример #2
0
		public CompilerTypeData(MosaType mosaType)
		{
			if (mosaType == null)
				throw new ArgumentNullException("mosaType");

			MosaType = mosaType;
		}
Пример #3
0
        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;
        }
Пример #8
0
        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);
        }
Пример #9
0
 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);
         }
     }
 }
Пример #10
0
        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();
            }
        }
Пример #11
0
        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;
        }
Пример #12
0
        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();
        }
Пример #13
0
        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;
            }
        }
Пример #14
0
        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);
            }
        }
Пример #15
0
        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!
                    }
                }
            }
        }
Пример #16
0
        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;
        }
Пример #17
0
        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);
        }
Пример #18
0
        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;
        }
Пример #20
0
 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));
 }
Пример #21
0
        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));
 }
Пример #25
0
 public static TypeSig GetTypeSig(this MosaType type)
 {
     return(type.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Signature);
 }
Пример #26
0
 /// <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;
 }
Пример #27
0
        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;
            }
        }
Пример #28
0
 /// <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);
 }
Пример #29
0
 /// <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;
 }
Пример #30
0
 protected override void Initialize()
 {
     exceptionType = TypeSystem.GetTypeByName("System", "Exception");
 }
Пример #31
0
 private bool HasInterface(MosaType type)
 {
     return(CheckBaseTypesForInterface(type) || CheckDerivedTypesForInterface(type));
 }
Пример #32
0
 protected string FormatMosaType(MosaType type)
 {
     return(type.Namespace + Type.Delimiter + type.Name);
 }
Пример #33
0
        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);
        }
Пример #34
0
 protected string FormatMosaType(MosaType type)
 {
     return type.Namespace + Type.Delimiter + type.Name;
 }
Пример #35
0
        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);
        }
Пример #36
0
 /// <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));
 }
Пример #38
0
 public static Operand Create(MosaType type, long value)
 {
     return(Operand.CreateConstant(type, (ulong)value));
 }
Пример #39
0
 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();
        }
Пример #41
0
 public void EnqueueForArrayResolve(MosaType type)
 {
     arrayResolveQueue.Enqueue(type);
 }
 protected BaseIRInstruction GetStoreParameterInstruction(MosaType type)
 {
     return(GetStoreParameterInstruction(type, Is32BitPlatform));
 }
Пример #43
0
 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));
 }
Пример #45
0
 public void TrackTypeAllocated(MosaType type)
 {
 }
Пример #46
0
 /// <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));
 }
Пример #47
0
 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));
 }
Пример #49
0
 /// <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);
        }
Пример #51
0
 /// <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;
 }
Пример #52
0
        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");
        }
Пример #53
0
 /// <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;
 }
Пример #54
0
 /// <summary>
 /// Allocates the virtual register.
 /// </summary>
 /// <param name="type">The type.</param>
 /// <returns></returns>
 public Operand Allocate(MosaType type)
 {
     return(Allocate(type, null));
 }
Пример #55
0
        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);
        }
Пример #56
0
        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);
        }
Пример #57
0
        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);
        }
Пример #58
0
 /// <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;
 }
Пример #59
0
 public void TrackTypeAllocated(MosaType type)
 {
 }
Пример #60
0
 /// <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));
 }