Пример #1
0
        public static void Assemble(XSharp.Assembler.Assembler aAssembler, OpType aOpType, uint aElementSize, bool debugEnabled, _MethodInfo aMethod, ILOpCode aOpCode)
        {
            XS.Comment("Arraytype: " + aOpType.StackPopTypes.Last().FullName);
            XS.Comment("Size: " + aElementSize);

            DoNullReferenceCheck(aAssembler, debugEnabled, 8);

            //Do check for index out of range
            var xBaseLabel = GetLabel(aMethod, aOpCode);
            var xNoIndexOutOfRangeExeptionLabel = xBaseLabel + "_NoIndexOutOfRangeException";
            var xIndexOutOfRangeExeptionLabel   = xBaseLabel + "_IndexOutOfRangeException";

            XS.Pop(EBX);                                     //get Position _, array, 0, index -> _, array, 0
            XS.Push(ESP, true, 4);                           // _, array, 0 => _, array, 0, array
            XS.Push(ESP, true, 12);                          // _, array, 0, array => _, array, 0, array, 0
            Ldlen.Assemble(aAssembler, debugEnabled, false); // _, array, 0, array, 0 -> _, array, 0, length
            XS.Pop(EAX);                                     //Length of array _, array, 0, length -> _, array, 0
            XS.Compare(EAX, EBX);
            XS.Jump(CPUx86.ConditionalTestEnum.LessThanOrEqualTo, xIndexOutOfRangeExeptionLabel);

            XS.Compare(EBX, 0);
            XS.Jump(CPUx86.ConditionalTestEnum.GreaterThanOrEqualTo, xNoIndexOutOfRangeExeptionLabel);

            XS.Label(xIndexOutOfRangeExeptionLabel);
            XS.Pop(EAX);
            XS.Pop(EAX);
            Call.DoExecute(aAssembler, aMethod, ExceptionHelperRefs.ThrowIndexOutOfRangeException, aOpCode, xNoIndexOutOfRangeExeptionLabel, debugEnabled);

            XS.Label(xNoIndexOutOfRangeExeptionLabel);
            XS.Push(EBX); //_, array, 0 -> _, array, 0, index

            // calculate element offset into array memory (including header)
            XS.Pop(EAX);
            XS.Set(EDX, aElementSize);
            XS.Multiply(EDX);
            XS.Add(EAX, (uint)(ObjectUtils.FieldDataOffset + 4));

            // pop the array now
            XS.Add(ESP, 4);
            XS.Pop(EDX);

            XS.Add(EDX, EAX);
            XS.Push(EDX);
        }
Пример #2
0
        public static void Assemble(Assembler aAssembler, uint aElementSize, _MethodInfo aMethod, ILOpCode aOpCode, bool debugEnabled)
        {
            DoNullReferenceCheck(aAssembler, debugEnabled, (int)(8 + Align(aElementSize, 4)));

            uint xStackSize = aElementSize;

            if (xStackSize % 4 != 0)
            {
                xStackSize += 4 - xStackSize % 4;
            }
            // Do index out of range check
            var xBaseLabel = GetLabel(aMethod, aOpCode);
            var xNoIndexOutOfRangeExeptionLabel = xBaseLabel + "_NoIndexOutOfRangeException";
            var xIndexOutOfRangeExeptionLabel   = xBaseLabel + "_IndexOutOfRangeException";

            XS.Push(ESP, displacement: 4 + 4 + (int)xStackSize); // _, array, 0, index, value * n  => _, array, 0, index, value * n, array
            XS.Push(0);                                          // _, array, 0, index, value * n, array => _, array, 0, index, value * n, array, 0
            Ldlen.Assemble(aAssembler, debugEnabled, false);     // _, array, 0, index, value * n, array, 0 -> _, array, 0, index, value * n, length
            XS.Pop(EAX);                                         //Length of array _, array, 0, index, value * n, length -> _, array, 0, index, value * n
            XS.Compare(EAX, ESP, sourceIsIndirect: true, sourceDisplacement: (int)xStackSize);
            XS.Jump(CPUx86.ConditionalTestEnum.LessThanOrEqualTo, xIndexOutOfRangeExeptionLabel);

            XS.Compare(EAX, 0);
            XS.Jump(CPUx86.ConditionalTestEnum.GreaterThanOrEqualTo, xNoIndexOutOfRangeExeptionLabel);

            XS.Label(xIndexOutOfRangeExeptionLabel);
            Call.DoExecute(aAssembler, aMethod, ExceptionHelperRefs.ThrowIndexOutOfRangeException, aOpCode, xNoIndexOutOfRangeExeptionLabel, debugEnabled);

            XS.Label(xNoIndexOutOfRangeExeptionLabel);

            // calculate element offset into array memory (including header)
            XS.Set(EAX, ESP, sourceDisplacement: (int)xStackSize); // the index
            XS.Set(EDX, aElementSize);
            XS.Multiply(EDX);
            XS.Add(EAX, ObjectUtils.FieldDataOffset + 4);

            XS.Set(EDX, ESP, sourceDisplacement: (int)xStackSize + 8); // the array
            XS.Add(EDX, EAX);
            XS.Push(EDX);

            XS.Pop(ECX);
            for (int i = (int)(aElementSize / 4) - 1; i >= 0; i -= 1)
            {
                new Comment(aAssembler, "Start 1 dword");
                XS.Pop(EBX);
                XS.Set(ECX, EBX, destinationIsIndirect: true);
                XS.Add(ECX, 4);
            }
            switch (aElementSize % 4)
            {
            case 1:
            {
                new Comment(aAssembler, "Start 1 byte");
                XS.Pop(EBX);
                XS.Set(ECX, BL, destinationIsIndirect: true);
                break;
            }

            case 2:
            {
                new Comment(aAssembler, "Start 1 word");
                XS.Pop(EBX);
                XS.Set(ECX, BX, destinationIsIndirect: true);
                break;
            }

            case 0:
            {
                break;
            }

            default:
                throw new Exception("Remainder size " + (aElementSize % 4) + " not supported!");
            }
            XS.Add(ESP, 12);
        }
Пример #3
0
        public static void Assemble(Assembler aAssembler, uint aElementSize, bool isSigned, _MethodInfo aMethod, ILOpCode aOpCode, bool debugEnabled)
        {
            //  stack     = index
            //  stack + 2 = array
            DoNullReferenceCheck(aAssembler, debugEnabled, 8);

            var xBaseLabel = GetLabel(aMethod, aOpCode);
            var xNoIndexOutOfRangeExeptionLabel = xBaseLabel + "_NoIndexOutOfRangeException";
            var xIndexOutOfRangeExeptionLabel   = xBaseLabel + "_IndexOutOfRangeException";

            XS.Pop(EBX);                                     //get Position _, array, 0, index -> _, array, 0
            XS.Push(ESP, true, 4);                           // _, array, 0 => _, array, 0, array
            XS.Push(ESP, true, 12);                          // _, array, 0, array => _, array, 0, array, 0
            Ldlen.Assemble(aAssembler, debugEnabled, false); // _, array, 0, array, 0 -> _, array, 0, length
            XS.Pop(EAX);                                     //Length of array _, array, 0, length -> _, array, 0
            XS.Compare(EAX, EBX);
            XS.Jump(CPUx86.ConditionalTestEnum.LessThanOrEqualTo, xIndexOutOfRangeExeptionLabel);

            XS.Compare(EBX, 0);
            XS.Jump(CPUx86.ConditionalTestEnum.GreaterThanOrEqualTo, xNoIndexOutOfRangeExeptionLabel);

            XS.Label(xIndexOutOfRangeExeptionLabel);
            XS.Pop(EAX);
            XS.Pop(EAX);
            Call.DoExecute(aAssembler, aMethod, ExceptionHelperRefs.ThrowIndexOutOfRangeException, aOpCode, xNoIndexOutOfRangeExeptionLabel, debugEnabled);

            XS.Label(xNoIndexOutOfRangeExeptionLabel);
            XS.Push(EBX); //_, array, 0 -> _, array, 0, index

            // calculate element offset into array memory (including header)
            XS.Pop(EAX);
            XS.Set(EDX, aElementSize);
            XS.Multiply(EDX);
            XS.Add(EAX, ObjectUtils.FieldDataOffset + 4);

            if (aElementSize > 4)
            {
                // we start copying the last bytes
                XS.Add(EAX, aElementSize - 4);
            }

            // pop the array now
            XS.Add(ESP, 4);
            XS.Pop(EDX);

            XS.Add(EDX, EAX);

            var xSizeLeft = aElementSize;

            while (xSizeLeft > 0)
            {
                var xCurrentStep = Math.Min(xSizeLeft, 4);
                if (xSizeLeft % 4 != 0)
                {
                    xCurrentStep = xSizeLeft % 4;
                }

                xSizeLeft = xSizeLeft - xCurrentStep;
                switch (xCurrentStep)
                {
                case 1:
                    if (isSigned)
                    {
                        XS.MoveSignExtend(ECX, EDX, sourceIsIndirect: true, size: RegisterSize.Byte8);
                    }
                    else
                    {
                        XS.MoveZeroExtend(ECX, EDX, sourceIsIndirect: true, size: RegisterSize.Byte8);
                    }
                    XS.Push(ECX);
                    break;

                case 2:
                    if (isSigned)
                    {
                        XS.MoveSignExtend(ECX, EDX, sourceIsIndirect: true, size: RegisterSize.Short16);
                    }
                    else
                    {
                        XS.MoveZeroExtend(ECX, EDX, sourceIsIndirect: true, size: RegisterSize.Short16);
                    }
                    XS.Push(ECX);
                    break;

                case 4:
                    // copy a full dword
                    XS.Push(EDX, true);
                    XS.Sub(EDX, 4); // move to previous 4 bytes
                    break;
                    //case 8:
                    //    new CPUx86.Push {DestinationReg = CPUx86.Registers.EDX, DestinationDisplacement = 4, DestinationIsIndirect = true};
                    //    XS.Push(XSRegisters.EDX, isIndirect: true);
                    //    break;
                }
            }
        }