Example #1
0
        public void Should_create_OffsetStatistics_with_correct_Max_values()
        {
            var statistics = OffsetStatistics.Create(OffsetStatisticType.Maximum, station, request);

            Assert.AreEqual((double)station.CMVMax / 10, statistics.CMV);
            Assert.AreEqual(station.CutFillMax, statistics.CutFill);
            Assert.AreEqual(station.ElevMax, statistics.Elevation);
            Assert.AreEqual((double)station.MDPMax / 10, statistics.MDP);
            Assert.AreEqual(station.PassCountMax, statistics.PassCount);
            Assert.AreEqual(station.TemperatureMax / 10, statistics.Temperature);
        }
Example #2
0
        public void Should_create_OffsetStatistics_with_correct_Avg_values()
        {
            var statistics = OffsetStatistics.Create(OffsetStatisticType.Average, station, request);

            Assert.AreEqual(station.CMVAvg / 10, statistics.CMV);
            Assert.AreEqual(station.CutFillAvg, statistics.CutFill);
            Assert.AreEqual(station.ElevAvg, statistics.Elevation);
            Assert.AreEqual(station.MDPAvg / 10, statistics.MDP);
            Assert.AreEqual(station.PassCountAvg, statistics.PassCount);
            Assert.AreEqual(station.TemperatureAvg / 10, statistics.Temperature);
        }
Example #3
0
        public void WriteTo(BinaryWriter writer)
        {
            OffsetStatistics stats = MethodDefinition.Body.UpdateInstructionOffsets();

            _extraOffset = stats.CodeUnits;
            Codes        = new ushort[stats.CodeUnits + stats.ExtraCodeUnits];

            foreach (var ins in MethodDefinition.Body.Instructions)
            {
                if (_ip != ins.Offset)
                {
                    throw new InstructionException(ins, "Instruction pointer do not match");
                }

                Codes[_ip] = (ushort)ins.OpCode;
                int registerMask;
                switch (ins.OpCode)
                {
                case OpCodes.Nop:
                case OpCodes.ReturnVoid:
                    _ip++;
                    break;

                case OpCodes.MoveResult:
                case OpCodes.MoveResultWide:
                case OpCodes.MoveResultObject:
                case OpCodes.MoveException:
                case OpCodes.Return:
                case OpCodes.ReturnWide:
                case OpCodes.ReturnObject:
                case OpCodes.MonitorEnter:
                case OpCodes.MonitorExit:
                case OpCodes.Throw:
                    // vAA
                    WritevAA(ins);
                    break;

                case OpCodes.MoveObject:
                case OpCodes.MoveWide:
                case OpCodes.Move:
                case OpCodes.ArrayLength:
                case OpCodes.NegInt:
                case OpCodes.NotInt:
                case OpCodes.NegLong:
                case OpCodes.NotLong:
                case OpCodes.NegFloat:
                case OpCodes.NegDouble:
                case OpCodes.IntToLong:
                case OpCodes.IntToFloat:
                case OpCodes.IntToDouble:
                case OpCodes.LongToInt:
                case OpCodes.LongToFloat:
                case OpCodes.LongToDouble:
                case OpCodes.FloatToInt:
                case OpCodes.FloatToLong:
                case OpCodes.FloatToDouble:
                case OpCodes.DoubleToInt:
                case OpCodes.DoubleToLong:
                case OpCodes.DoubleToFloat:
                case OpCodes.IntToByte:
                case OpCodes.IntToChar:
                case OpCodes.IntToShort:
                case OpCodes.AddInt2Addr:
                case OpCodes.SubInt2Addr:
                case OpCodes.MulInt2Addr:
                case OpCodes.DivInt2Addr:
                case OpCodes.RemInt2Addr:
                case OpCodes.AndInt2Addr:
                case OpCodes.OrInt2Addr:
                case OpCodes.XorInt2Addr:
                case OpCodes.ShlInt2Addr:
                case OpCodes.ShrInt2Addr:
                case OpCodes.UshrInt2Addr:
                case OpCodes.AddLong2Addr:
                case OpCodes.SubLong2Addr:
                case OpCodes.MulLong2Addr:
                case OpCodes.DivLong2Addr:
                case OpCodes.RemLong2Addr:
                case OpCodes.AndLong2Addr:
                case OpCodes.OrLong2Addr:
                case OpCodes.XorLong2Addr:
                case OpCodes.ShlLong2Addr:
                case OpCodes.ShrLong2Addr:
                case OpCodes.UshrLong2Addr:
                case OpCodes.AddFloat2Addr:
                case OpCodes.SubFloat2Addr:
                case OpCodes.MulFloat2Addr:
                case OpCodes.DivFloat2Addr:
                case OpCodes.RemFloat2Addr:
                case OpCodes.AddDouble2Addr:
                case OpCodes.SubDouble2Addr:
                case OpCodes.MulDouble2Addr:
                case OpCodes.DivDouble2Addr:
                case OpCodes.RemDouble2Addr:
                    // vA, vB
                    WritevA(ins);
                    WritevB(ins);
                    break;

                case OpCodes.MoveWideFrom16:
                case OpCodes.MoveFrom16:
                case OpCodes.MoveObjectFrom16:
                    // vAA, vBBBB
                    WritevAA(ins);
                    WritevBBBB(ins);
                    break;

                case OpCodes.Move16:
                case OpCodes.MoveObject16:
                    // vAAAA, vBBBB
                    WritevAAAA(ins);
                    WritevBBBB(ins);
                    break;

                case OpCodes.Const4:
                    // vA, #+B
                    WritevA(ins);
                    WriteNibble(ins);
                    break;

                case OpCodes.Const16:
                case OpCodes.ConstWide16:
                    // vAA, #+BBBB
                    WritevAA(ins);
                    WriteShort(ins);
                    break;

                case OpCodes.Const:
                case OpCodes.ConstWide32:
                    // vAA, #+BBBBBBBB
                    WritevAA(ins);
                    WriteInt(ins);
                    break;

                case OpCodes.FillArrayData:
                    // vAA, #+BBBBBBBB
                    WritevAA(ins);
                    WriteInt(_extraOffset - ins.Offset, ref _ip);
                    WriteArrayData(ins);
                    break;

                case OpCodes.ConstHigh16:
                    // vAA, #+BBBB0000
                    WritevAA(ins);
                    WriteShort(ins, 16);
                    break;

                case OpCodes.ConstWide:
                    // vAA, #+BBBBBBBBBBBBBBBB
                    WritevAA(ins);
                    WriteLong(ins);
                    break;

                case OpCodes.ConstWideHigh16:
                    // vAA, #+BBBB000000000000
                    WritevAA(ins);
                    WriteShort(ins, 48);
                    break;

                case OpCodes.ConstString:
                    // vAA, string@BBBB
                    WritevAA(ins);
                    WriteShortStringIndex(ins);
                    break;

                case OpCodes.ConstStringJumbo:
                    // vAA, string@BBBBBBBB
                    WritevAA(ins);
                    WriteIntStringIndex(ins);
                    break;

                case OpCodes.ConstClass:
                case OpCodes.NewInstance:
                case OpCodes.CheckCast:
                    // vAA, type@BBBB
                    WritevAA(ins);
                    WriteShortTypeIndex(ins);
                    break;

                case OpCodes.InstanceOf:
                case OpCodes.NewArray:
                    // vA, vB, type@CCCC
                    WritevA(ins);
                    WritevB(ins);
                    WriteShortTypeIndex(ins);
                    break;

                case OpCodes.FilledNewArray:
                    // {vD, vE, vF, vG, vA}, type@CCCC
                    registerMask  = GetRegisterMask(ins);
                    Codes[_ip++] |= (ushort)(registerMask >> 16 << 8);
                    WriteShortTypeIndex(ins);
                    Codes[_ip++] |= (ushort)(registerMask << 12 >> 12);
                    break;

                case OpCodes.FilledNewArrayRange:
                    // {vCCCC .. vNNNN}, type@BBBB

                    /*registerCount = Upper[Ip++] << 16;
                     * ins.Operand = Dex.TypeReferences[ReadShort(ref Ip)];
                     * ReadvBBBB(ins);
                     * for (int i = 1; i < registerCount; i++)
                     *  ins.Registers.Add(registers[i + ins.Registers[0].Index]);*/
                    throw new NotImplementedException();

                case OpCodes.Goto:
                    // +AA
                    WriteSbyteInstructionOffset(ins);
                    break;

                case OpCodes.Goto16:
                    // +AAAA
                    _ip++;
                    WriteShortInstructionOffset(ins);
                    break;

                case OpCodes.Goto32:
                    // +AAAAAAAA
                    _ip++;
                    WriteIntInstructionOffset(ins);
                    break;

                case OpCodes.PackedSwitch:
                    // vAA, +BBBBBBBB
                    WritevAA(ins);
                    WriteInt(_extraOffset - ins.Offset, ref _ip);
                    WritePackedSwitch(ins);
                    break;

                case OpCodes.SparseSwitch:
                    // vAA, +BBBBBBBB
                    WritevAA(ins);
                    WriteInt(_extraOffset - ins.Offset, ref _ip);
                    WriteSparseSwitch(ins);
                    break;

                case OpCodes.CmplFloat:
                case OpCodes.CmpgFloat:
                case OpCodes.CmplDouble:
                case OpCodes.CmpgDouble:
                case OpCodes.CmpLong:
                case OpCodes.Aget:
                case OpCodes.AgetWide:
                case OpCodes.AgetObject:
                case OpCodes.AgetBoolean:
                case OpCodes.AgetByte:
                case OpCodes.AgetChar:
                case OpCodes.AgetShort:
                case OpCodes.Aput:
                case OpCodes.AputWide:
                case OpCodes.AputObject:
                case OpCodes.AputBoolean:
                case OpCodes.AputByte:
                case OpCodes.AputChar:
                case OpCodes.AputShort:
                case OpCodes.AddInt:
                case OpCodes.SubInt:
                case OpCodes.MulInt:
                case OpCodes.DivInt:
                case OpCodes.RemInt:
                case OpCodes.AndInt:
                case OpCodes.OrInt:
                case OpCodes.XorInt:
                case OpCodes.ShlInt:
                case OpCodes.ShrInt:
                case OpCodes.UshrInt:
                case OpCodes.AddLong:
                case OpCodes.SubLong:
                case OpCodes.MulLong:
                case OpCodes.DivLong:
                case OpCodes.RemLong:
                case OpCodes.AndLong:
                case OpCodes.OrLong:
                case OpCodes.XorLong:
                case OpCodes.ShlLong:
                case OpCodes.ShrLong:
                case OpCodes.UshrLong:
                case OpCodes.AddFloat:
                case OpCodes.SubFloat:
                case OpCodes.MulFloat:
                case OpCodes.DivFloat:
                case OpCodes.RemFloat:
                case OpCodes.AddDouble:
                case OpCodes.SubDouble:
                case OpCodes.MulDouble:
                case OpCodes.DivDouble:
                case OpCodes.RemDouble:
                    // vAA, vBB, vCC
                    WritevAA(ins);
                    WritevBB(ins);
                    WritevCC(ins);
                    break;

                case OpCodes.IfEq:
                case OpCodes.IfNe:
                case OpCodes.IfLt:
                case OpCodes.IfGe:
                case OpCodes.IfGt:
                case OpCodes.IfLe:
                    // vA, vB, +CCCC
                    WritevA(ins);
                    WritevB(ins);
                    WriteShortInstructionOffset(ins);
                    break;

                case OpCodes.IfEqz:
                case OpCodes.IfNez:
                case OpCodes.IfLtz:
                case OpCodes.IfGez:
                case OpCodes.IfGtz:
                case OpCodes.IfLez:
                    // vAA, +BBBB
                    WritevAA(ins);
                    WriteShortInstructionOffset(ins);
                    break;

                case OpCodes.Iget:
                case OpCodes.IgetWide:
                case OpCodes.IgetObject:
                case OpCodes.IgetBoolean:
                case OpCodes.IgetByte:
                case OpCodes.IgetChar:
                case OpCodes.IgetShort:
                case OpCodes.Iput:
                case OpCodes.IputWide:
                case OpCodes.IputObject:
                case OpCodes.IputBoolean:
                case OpCodes.IputByte:
                case OpCodes.IputChar:
                case OpCodes.IputShort:
                    // vA, vB, field@CCCC
                    WritevA(ins);
                    WritevB(ins);
                    WriteShortFieldIndex(ins);
                    break;

                case OpCodes.Sget:
                case OpCodes.SgetWide:
                case OpCodes.SgetObject:
                case OpCodes.SgetBoolean:
                case OpCodes.SgetByte:
                case OpCodes.SgetChar:
                case OpCodes.SgetShort:
                case OpCodes.Sput:
                case OpCodes.SputWide:
                case OpCodes.SputObject:
                case OpCodes.SputBoolean:
                case OpCodes.SputByte:
                case OpCodes.SputChar:
                case OpCodes.SputShort:
                    // vAA, field@BBBB
                    WritevAA(ins);
                    WriteShortFieldIndex(ins);
                    break;

                case OpCodes.InvokeVirtual:
                case OpCodes.InvokeSuper:
                case OpCodes.InvokeDirect:
                case OpCodes.InvokeStatic:
                case OpCodes.InvokeInterface:
                    // {vD, vE, vF, vG, vA}, meth@CCCC
                    registerMask  = GetRegisterMask(ins);
                    Codes[_ip++] |= (ushort)(registerMask >> 16 << 8);
                    WriteShortMethodIndex(ins);
                    Codes[_ip++] |= (ushort)(registerMask << 12 >> 12);
                    break;

                case OpCodes.InvokeVirtualRange:
                case OpCodes.InvokeSuperRange:
                case OpCodes.InvokeDirectRange:
                case OpCodes.InvokeStaticRange:
                case OpCodes.InvokeInterfaceRange:
                    // {vCCCC .. vNNNN}, meth@BBBB
                    WriteSByte(ins.Registers.Count);
                    WriteShortMethodIndex(ins);
                    Codes[_ip++] |= (ushort)CheckRegister(ins, 0, 0xFFFF);
                    break;

                case OpCodes.AddIntLit16:
                case OpCodes.RsubInt:
                case OpCodes.MulIntLit16:
                case OpCodes.DivIntLit16:
                case OpCodes.RemIntLit16:
                case OpCodes.AndIntLit16:
                case OpCodes.OrIntLit16:
                case OpCodes.XorIntLit16:
                    // vA, vB, #+CCCC
                    WritevA(ins);
                    WritevB(ins);
                    WriteShort(ins);
                    break;

                case OpCodes.AddIntLit8:
                case OpCodes.RsubIntLit8:
                case OpCodes.MulIntLit8:
                case OpCodes.DivIntLit8:
                case OpCodes.RemIntLit8:
                case OpCodes.AndIntLit8:
                case OpCodes.OrIntLit8:
                case OpCodes.XorIntLit8:
                case OpCodes.ShlIntLit8:
                case OpCodes.ShrIntLit8:
                case OpCodes.UshrIntLit8:
                    // vAA, vBB, #+CC
                    WritevAA(ins);
                    WritevBB(ins);
                    WriteSByte(ins);
                    break;

                default:
                    throw new NotImplementedException(string.Concat("Unknown opcode:", ins.OpCode));
                }

                LookupLast.Add(ins, _ip - 1);
            }

            if (_ip != stats.CodeUnits)
            {
                throw new MalformedException("Instruction pointer out of range");
            }

            if (_extraOffset != stats.CodeUnits + stats.ExtraCodeUnits)
            {
                throw new MalformedException("Data pointer out of range");
            }

            writer.Write(_extraOffset);
            for (var i = 0; i < _extraOffset; i++)
            {
                writer.Write(Codes[i]);
            }
        }