Exemplo n.º 1
0
        public CilGenericType(RuntimeType type, IMetadataModule referencingModule, GenericInstSigType genericTypeInstanceSignature, ISignatureContext signatureContext)
            : base(type.Token, type.Module)
        {
            this.signature = genericTypeInstanceSignature;
            this.signatureContext = signatureContext;
            this.signatureModule = referencingModule;

            this.Methods = this.GetMethods();
            this.Fields = this.GetFields();
        }
Exemplo n.º 2
0
        /// <summary>
        /// Parses the signature.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        /// <param name="index">The index.</param>
        protected override void ParseSignature(ISignatureContext context, byte[] buffer, ref int index)
        {
            if (0x0A != buffer[index])
                throw new InvalidOperationException(@"Invalid signature.");
            index++;

            int genArgCount = Utilities.ReadCompressedInt32(buffer, ref index);
            this.types = new SigType[genArgCount];
            for (int i = 0; i < genArgCount; i++)
                this.types[i] = SigType.ParseTypeSignature(context, buffer, ref index);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Loads the signature.
        /// </summary>
        /// <param name="provider">The provider.</param>
        /// <param name="token">The token.</param>
        public void LoadSignature(ISignatureContext context, IMetadataProvider provider, TokenTypes token)
        {
            byte[] buffer;
            provider.Read(token, out buffer);

            int index = 0;
            this.ParseSignature(context, buffer, ref index);
            Debug.Assert(index == buffer.Length, @"Signature parser didn't complete.");

            this.token = token;
        }
Exemplo n.º 4
0
        public CilGenericMethod(CilRuntimeMethod method, MethodSignature signature, ISignatureContext signatureContext)
            : base(method.Token, method.Module, method.DeclaringType)
        {
            this.genericMethod = method;
            this.signatureContext = signatureContext;

            this.Signature = signature;

            this.Attributes = method.Attributes;
            this.ImplAttributes = method.ImplAttributes;
            this.Rva = method.Rva;
            this.Parameters = method.Parameters;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Computes the field offset.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="metadataProvider">The metadata provider.</param>
        /// <param name="architecture">The architecture.</param>
        /// <returns></returns>
        public static int ComputeFieldOffset(ISignatureContext context, TokenTypes token, IMetadataProvider metadataProvider, IArchitecture architecture)
        {
            Metadata.Tables.TypeDefRow typeDefinition;
            Metadata.Tables.TypeDefRow followingTypeDefinition;
            metadataProvider.Read(token, out typeDefinition);
            metadataProvider.Read(token + 1, out followingTypeDefinition);

            int result = 0;
            TokenTypes fieldList = typeDefinition.FieldList;
            while (fieldList != token)
                result += FieldSize(context, fieldList++, metadataProvider, architecture);

            return result;
        }
Exemplo n.º 6
0
        /// <summary>
        /// Fields the size.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="metadataProvider">The metadata provider.</param>
        /// <param name="architecture">The architecture.</param>
        /// <returns></returns>
        public static int FieldSize(ISignatureContext context, TokenTypes field, IMetadataProvider metadataProvider, IArchitecture architecture)
        {
            Metadata.Tables.FieldRow fieldRow;
            metadataProvider.Read(field, out fieldRow);
            FieldSignature signature = Signature.FromMemberRefSignatureToken(context, metadataProvider, fieldRow.SignatureBlobIdx) as FieldSignature;

            // If the field is another struct, we have to dig down and compute its size too.
            if (signature.Type.Type == CilElementType.ValueType)
            {
                TokenTypes valueTypeSig = ValueTokenTypeFromSignature(metadataProvider, fieldRow.SignatureBlobIdx);
                return ComputeTypeSize(context, valueTypeSig, metadataProvider, architecture);
            }

            int size, alignment;
            architecture.GetTypeRequirements(signature.Type, out size, out alignment);
            return size;
        }
Exemplo n.º 7
0
        /// <summary>
        /// Froms the member ref signature token.
        /// </summary>
        /// <param name="provider">The provider.</param>
        /// <param name="token">The token.</param>
        /// <returns></returns>
        public static Signature FromMemberRefSignatureToken(ISignatureContext context, IMetadataProvider provider, TokenTypes token)
        {
            Signature result;
            int index = 0;
            byte[] buffer;
            provider.Read(token, out buffer);

            if (0x06 == buffer[0])
            {
                result = new FieldSignature();
                result.ParseSignature(context, buffer, ref index);
            }
            else
            {
                result = new MethodSignature();
                result.ParseSignature(context, buffer, ref index);
            }
            Debug.Assert(index == buffer.Length, @"Not all signature bytes read.");
            return result;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Computes the size of the type.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="metadataProvider">The metadata provider.</param>
        /// <param name="architecture">The architecture.</param>
        /// <returns></returns>
        public static int ComputeTypeSize(ISignatureContext context, TokenTypes token, IMetadataProvider metadataProvider, IArchitecture architecture)
        {
            Metadata.Tables.TypeDefRow typeDefinition;
            Metadata.Tables.TypeDefRow followingTypeDefinition = new Mosa.Runtime.Metadata.Tables.TypeDefRow();
            metadataProvider.Read(token, out typeDefinition);
            try
            {
                metadataProvider.Read(token + 1, out followingTypeDefinition);
            }
            catch (System.Exception)
            {
            }

            int result = 0;
            TokenTypes fieldList = typeDefinition.FieldList;
            TokenTypes last = metadataProvider.GetMaxTokenValue(TokenTypes.Field);
            while (fieldList != followingTypeDefinition.FieldList && fieldList != last)
                result += FieldSize(context, fieldList++, metadataProvider, architecture);

            return result;
        }
Exemplo n.º 9
0
 /// <summary>
 /// Parses the specified provider.
 /// </summary>
 /// <param name="provider">The provider.</param>
 /// <param name="token">The token.</param>
 /// <returns></returns>
 public static LocalVariableSignature Parse(ISignatureContext context, IMetadataProvider provider, TokenTypes token)
 {
     var signature = new LocalVariableSignature();
     signature.LoadSignature(context, provider, token);
     return signature;
 }
Exemplo n.º 10
0
        private SigType ApplySpecification(ISignatureContext context, MethodSpecSignature specification, SigType sigType)
        {
            SigType result = sigType;

            if (sigType is VarSigType)
            {
                result = context.GetGenericTypeArgument(((VarSigType)sigType).Index);
            }
            else if (sigType is MVarSigType)
            {
                result = specification.Types[((MVarSigType)sigType).Index];
            }

            Debug.WriteLine(String.Format(@"Replaced {0} by {1}.", sigType, result));
            return result;
        }
Exemplo n.º 11
0
        /// <summary>
        /// Parses the signature.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        /// <param name="index">The index.</param>
        protected override sealed void ParseSignature(ISignatureContext context, byte[] buffer, ref int index)
        {
            // Check for instance signature
            if (HAS_THIS == (buffer[index] & HAS_THIS))
            {
                _hasThis = true;
            }
            if (HAS_EXPLICIT_THIS == (buffer[index] & HAS_EXPLICIT_THIS))
                _hasExplicitThis = true;
            if (GENERIC == (buffer[index] & GENERIC))
            {
                _callingConvention = CallingConvention.Generic;
                _genericParameterCount = Utilities.ReadCompressedInt32(buffer, ref index);
            }
            else if (VARARG == (buffer[index] & VARARG))
            {
                _callingConvention = CallingConvention.Vararg;
            }
            else if (0x00 != (buffer[index] & 0x1F))
            {
                throw new InvalidOperationException(@"Invalid method definition signature.");
            }

            index++;

            // Number of parameters
            int paramCount = Utilities.ReadCompressedInt32(buffer, ref index);
            _parameters = new SigType[paramCount];

            // Read the return type
            _returnType = SigType.ParseTypeSignature(context, buffer, ref index);

            // Read all parameters
            for (int i = 0; i < paramCount; i++)
                _parameters[i] = SigType.ParseTypeSignature(context, buffer, ref index);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MethodSignature"/> class.
        /// </summary>
        /// <param name="context">The context of the generic method spec signature.</param>
        /// <param name="signature">The signature of the generic method.</param>
        /// <param name="specification">The signature specifying replacements for the generic signature.</param>
        public MethodSignature(ISignatureContext context, MethodSignature signature, MethodSpecSignature specification)
        {
            if (context == null)
                throw new ArgumentNullException(@"context");
            if (signature == null)
                throw new ArgumentNullException(@"signature");
            if (specification == null)
                throw new ArgumentNullException(@"specification");

            this._callingConvention = signature.CallingConvention;
            this._hasExplicitThis = signature.HasExplicitThis;
            this._hasThis = signature.HasThis;
            this._genericParameterCount = 0;

            int length = signature.Parameters.Length;
            this._parameters = new SigType[length];
            for (int index = 0; index < length; index++)
            {
                this._parameters[index] = this.ApplySpecification(context, specification, signature.Parameters[index]);
            }
            this._returnType = this.ApplySpecification(context, specification, signature.ReturnType);
        }
        private int ReserveStackSizeForCall(Context ctx, IMetadataProvider metadata, ISignatureContext signatureContext, IEnumerable<Operand> operands)
        {
            int stackSize = CalculateStackSizeForParameters(signatureContext, operands, metadata);
            if (stackSize != 0)
            {
                RegisterOperand esp = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.ESP);

                ctx.AppendInstruction(CPUx86.Instruction.SubInstruction, esp, new ConstantOperand(esp.Type, stackSize));
                ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(architecture.NativeType, GeneralPurposeRegister.EDX), esp);
            }

            return stackSize;
        }
        /// <summary>
        /// Calculates the remaining space.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="operandStack">The operand stack.</param>
        /// <param name="space">The space.</param>
        private void PushOperands(ISignatureContext context, Context ctx, Stack<Operand> operandStack, int space, IMetadataProvider metadata)
        {
            while (operandStack.Count != 0)
            {
                Operand operand = operandStack.Pop();
                int size, alignment;

                architecture.GetTypeRequirements(operand.Type, out size, out alignment);

                if (operand.Type.Type == CilElementType.ValueType)
                    size = ObjectModelUtility.ComputeTypeSize(context, (operand.Type as ValueTypeSigType).Token, metadata, architecture);

                space -= size;
                Push(ctx, operand, space, size);
            }
        }
        /// <summary>
        /// Calculates the stack size for parameters.
        /// </summary>
        /// <param name="operands">The operands.</param>
        /// <param name="metadata">The metadata.</param>
        /// <returns></returns>
        private int CalculateStackSizeForParameters(ISignatureContext context, IEnumerable<Operand> operands, IMetadataProvider metadata)
        {
            int result = 0;
            int size, alignment;

            foreach (Operand op in operands) {
                this.architecture.GetTypeRequirements(op.Type, out size, out alignment);

                if (op.Type.Type == CilElementType.ValueType)
                {
                    size = ObjectModelUtility.ComputeTypeSize(context, (op.Type as Runtime.Metadata.Signatures.ValueTypeSigType).Token, metadata, architecture);
                }

                result += size;
            }
            return result;
        }
Exemplo n.º 16
0
 /// <summary>
 /// Parses the signature.
 /// </summary>
 /// <param name="buffer">The buffer.</param>
 /// <param name="index">The index.</param>
 protected abstract void ParseSignature(ISignatureContext context, byte[] buffer, ref int index);
Exemplo n.º 17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MethodSpecSignature"/> class.
 /// </summary>
 public MethodSpecSignature(ISignatureContext outerContext)
 {
     this.outerContext = outerContext;
 }
Exemplo n.º 18
0
        /// <summary>
        /// Parses the signature.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        /// <param name="index">The index.</param>
        protected override void ParseSignature(ISignatureContext context, byte[] buffer, ref int index)
        {
            // Check signature identifier
            if (buffer[index++] != 0x07)
                throw new ArgumentException(@"Token doesn't represent a local variable signature.", @"token");

            // Retrieve the number of locals
            int count = Utilities.ReadCompressedInt32(buffer, ref index);
            if (0 != count)
            {
                this.types = new SigType[count];
                for (int i = 0; i < count; i++)
                {
                    this.types[i] = SigType.ParseTypeSignature(context, buffer, ref index);
                }
            }
        }
Exemplo n.º 19
0
 /// <summary>
 /// Calculates the stack size for parameters.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <returns></returns>
 private int CalculateStackSizeForParameters(ISignatureContext context, Context ctx, IMetadataProvider metadata)
 {
     return CalculateStackSizeForParameters(context, ctx.Operands, ctx.InvokeTarget.Signature.HasThis, metadata);
 }
Exemplo n.º 20
0
        /// <summary>
        /// Expands the given invoke instruction to perform the method call.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <returns>
        /// A single instruction or an array of instructions, which appropriately represent the method call.
        /// </returns>
        void ICallingConvention.Expand(ISignatureContext context, Context ctx, IMetadataProvider metadata)
        {
            /*
             * Calling convention is right-to-left, pushed on the stack. Return value in EAX for integral
             * types 4 bytes or less, XMM0 for floating point and EAX:EDX for 64-bit. If this is a method
             * of a type, the this argument is moved to ECX right before the call.
             *
             */

            Mosa.Runtime.Vm.RuntimeMethod invokeTarget = ctx.InvokeTarget;
            Operand result = ctx.Result;
            Operand operand1 = ctx.Operand1;

            List<Operand> operands = new List<Operand>();
            operands.AddRange(ctx.Operands);

            int resultCount = ctx.ResultCount;
            int operandCount = ctx.OperandCount;

            SigType I = new SigType(CilElementType.I);
            RegisterOperand esp = new RegisterOperand(I, GeneralPurposeRegister.ESP);
            int stackSize = CalculateStackSizeForParameters(context, operands, invokeTarget.Signature.HasThis, metadata);

            ctx.SetInstruction(CPUx86.Instruction.NopInstruction);
            if (stackSize != 0)
            {
                ctx.AppendInstruction(CPUx86.Instruction.SubInstruction, esp, new ConstantOperand(I, stackSize));
                ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(architecture.NativeType, GeneralPurposeRegister.EDX), esp);

                Stack<Operand> operandStack = GetOperandStackFromInstruction(operands, operandCount, invokeTarget.Signature.HasThis);

                int space = stackSize;
                CalculateRemainingSpace(context, ctx, operandStack, ref space, metadata);
            }

            if (invokeTarget.Signature.HasThis)
            {
                RegisterOperand ecx = new RegisterOperand(I, GeneralPurposeRegister.ECX);
                RegisterOperand eax = new RegisterOperand(I, GeneralPurposeRegister.EAX);
                //ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, eax, operand1);
                //ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand (new SigType(CilElementType.Ptr), GeneralPurposeRegister.EDX, new IntPtr(0)), eax);
            }

            ctx.AppendInstruction(IR.Instruction.CallInstruction, invokeTarget);

            if (stackSize != 0)
                ctx.AppendInstruction(CPUx86.Instruction.AddInstruction, esp, new ConstantOperand(I, stackSize));

            if (resultCount > 0)
                if (result.StackType == StackTypeCode.Int64)
                    MoveReturnValueTo64Bit(result, ctx);
                else
                    MoveReturnValueTo32Bit(result, ctx);

            //ctx.Remove();
        }
        /// <summary>
        /// Expands the given invoke instruction to perform the method call.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <returns>
        /// A single instruction or an array of instructions, which appropriately represent the method call.
        /// </returns>
        public void MakeCall(Context ctx, ISignatureContext context, IMetadataProvider metadata)
        {
            /*
             * Calling convention is right-to-left, pushed on the stack. Return value in EAX for integral
             * types 4 bytes or less, XMM0 for floating point and EAX:EDX for 64-bit. If this is a method
             * of a type, the this argument is moved to ECX right before the call.
             *
             */

            Operand invokeTarget = ctx.Operand1;
            Operand result = ctx.Result;
            Stack<Operand> operands = this.BuildOperandStack(ctx);

            ctx.ReplaceInstructionOnly(CPUx86.Instruction.NopInstruction);
            ctx.OperandCount = 0;
            ctx.Result = null;

            int stackSize = this.ReserveStackSizeForCall(ctx, metadata, context, operands);
            if (stackSize != 0)
            {
                this.PushOperands(context, ctx, operands, stackSize, metadata);
            }

            ctx.AppendInstruction(CPUx86.Instruction.CallInstruction, null, invokeTarget);

            if (stackSize != 0)
            {
                this.FreeStackAfterCall(ctx, stackSize);
            }

            this.CleanupReturnValue(ctx, result);
        }
Exemplo n.º 22
0
 /// <summary>
 /// Parses the signature.
 /// </summary>
 /// <param name="buffer">The buffer.</param>
 /// <param name="index">The index.</param>
 protected override void ParseSignature(ISignatureContext context, byte[] buffer, ref int index)
 {
     throw new Exception("The method or operation is not implemented.");
 }