예제 #1
0
        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other">An object to compare with this object.</param>
        /// <returns>
        /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
        /// </returns>
        public override bool Equals(SigType other)
        {
            SZArraySigType szast = other as SZArraySigType;

            if (szast == null)
            {
                return(false);
            }

            return(base.Equals(other) == true && _elementType.Equals(szast._elementType) && CustomMod.Equals(_customMods, szast._customMods));
        }
예제 #2
0
        /// <summary>
        /// Validates the instruction operands and creates a matching variable for the result.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="compiler">The compiler.</param>
        public override void Validate(Context ctx, IMethodCompiler compiler)
        {
            base.Validate(ctx, compiler);

            Mosa.Runtime.Metadata.Signatures.SZArraySigType arrayType = ctx.Operand1.Type as Mosa.Runtime.Metadata.Signatures.SZArraySigType;
            if (arrayType == null)
            {
                throw new InvalidProgramException(@"Operand to ldlen is not a vector.");
            }

            ctx.Result = compiler.CreateTemporary(new SigType(CilElementType.I));
        }
예제 #3
0
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(Context ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            // Read the type specification
            Token token = decoder.DecodeTokenType();

            // FIXME: If ctx.Operands1 is an integral constant, we can infer the maximum size of the array
            // and instantiate an ArrayTypeSpecification with max. sizes. This way we could eliminate bounds
            // checks in an optimization stage later on, if we find that a value never exceeds the array
            // bounds.
            var resultType = new SZArraySigType(null, new ClassSigType(token));
            ctx.Result = decoder.Compiler.CreateTemporary(resultType);
        }
        /// <summary>
        /// Parses an SZArray attribute value.
        /// </summary>
        /// <param name="module">The metadata module, which contains the attribute blob.</param>
        /// <param name="reader">The binary reader used to read From the attribute blob.</param>
        /// <param name="sigType">Type of the SZArray.</param>
        /// <returns>An Array, which represents the SZArray definition.</returns>
        private static object ParseSZArrayArg(IMetadataModule module, BinaryReader reader, SZArraySigType sigType)
        {
            // Return value
            Array result;

            // Determine the number of elements
            int numElements = reader.ReadInt32();
            if (-1 == numElements)
                return null;

            // Retrieve the array element type
            Type elementType = GetTypeFromSigType(sigType);
            Debug.Assert(null != elementType, @"Failed to get System.Type for SigType.");
            result = Array.CreateInstance(elementType, numElements);
            for (int idx = 0; idx < numElements; idx++) {
                object item = ParseElem(module, reader, sigType.ElementType);
                result.SetValue(item, idx);
            }

            return result;
        }
 private Operand LoadArrayBaseAddress(Context ctx, SZArraySigType arraySignatureType, Operand arrayOperand)
 {
     Operand arrayAddress = this.MethodCompiler.CreateTemporary(new PtrSigType(arraySignatureType.ElementType));
     Operand fixedOffset = new ConstantOperand(BuiltInSigType.Int32, 12);
     ctx.SetInstruction(Instruction.AddSInstruction, arrayAddress, arrayOperand, fixedOffset);
     return arrayAddress;
 }
        private Operand CalculateArrayElementOffset(Context ctx, SZArraySigType arraySignatureType, Operand arrayIndexOperand)
        {
            int elementSizeInBytes = 0, alignment = 0;
            this.Architecture.GetTypeRequirements(arraySignatureType.ElementType, out elementSizeInBytes, out alignment);

            //
            // The sequence we're emitting is:
            //
            //      offset = arrayIndexOperand * elementSize
            //      temp = offset + 12
            //      result = *(arrayOperand * temp)
            //
            // The array data starts at offset 12 from the array object itself. The 12 is a hardcoded assumption
            // of x86, which might change for other platforms. We need to refactor this into some helper classes.
            //

            Operand elementOffset = this.MethodCompiler.CreateTemporary(BuiltInSigType.Int32);
            Operand elementSizeOperand = new ConstantOperand(BuiltInSigType.Int32, elementSizeInBytes);
            ctx.AppendInstruction(IR.Instruction.MulSInstruction, elementOffset, arrayIndexOperand, elementSizeOperand);

            return elementOffset;
        }