Exemplo n.º 1
0
        public static CliToken Parse(BytecodeReader reader)
        {
            var result = new CliToken();
            var count  = reader.ReadUInt32();

            for (int i = 0; i < count; i++)
            {
                result.Numbers.Add(reader.ReadDouble());
            }
            return(result);
        }
        public static ConstantPool ReadConstantPool(BytecodeReader reader, ushort constantPoolCount)
        {
            // TODO: check if long and double constants reading right
            ConstantPool constantPool  = new ConstantPool();
            int          a             = 0;
            var          tagDictionary = new Dictionary <int, Action>();

            tagDictionary.Add(1, () =>
            {
                ushort length = reader.ReadUShort();
                String value  = reader.ReadString(length);
                constantPool.AddConstantUtf8(new ConstantUtf8(length, value));
            });
            tagDictionary.Add(3, () => constantPool.AddConstantInteger(reader.ReadInt()));
            tagDictionary.Add(4, () => constantPool.AddConstantFloat(reader.ReadFloat()));
            tagDictionary.Add(5, () => constantPool.AddConstantLong(reader.ReadLong()));
            tagDictionary.Add(6, () => constantPool.AddConstantDouble(reader.ReadDouble()));
            tagDictionary.Add(7, () => constantPool.AddConstantClass(new ConstantClass(reader.ReadUShort())));
            tagDictionary.Add(8, () => constantPool.AddConstantString(new ConstantString(reader.ReadUShort())));
            tagDictionary.Add(9, () => constantPool.AddConstantFieldRef(new ConstantFieldRef(reader.ReadUShort(), reader.ReadUShort())));
            tagDictionary.Add(10, () => constantPool.AddConstantMethodRef(new ConstantMethodRef(reader.ReadUShort(), reader.ReadUShort())));
            tagDictionary.Add(11, () => constantPool.AddConstantInterfaceMethodRef(new ConstantInterfaceMethodRef(reader.ReadUShort(), reader.ReadUShort())));
            tagDictionary.Add(12, () => constantPool.AddConstantNameAndType(new ConstantNameAndType(reader.ReadUShort(), reader.ReadUShort())));
            tagDictionary.Add(15, () => constantPool.AddConstantMethodHandle(new ConstantMethodHandle(reader.ReadByte(), reader.ReadUShort())));
            tagDictionary.Add(16, () => constantPool.AddConstantMethodType(new ConstantMethodType(reader.ReadUShort())));
            tagDictionary.Add(18, () => constantPool.AddConstantInvokeDynamic(new ConstantInvokeDynamic(reader.ReadUShort(), reader.ReadUShort())));
            tagDictionary.Add(19, () => constantPool.AddConstantModule(new ConstantModule(reader.ReadUShort())));
            tagDictionary.Add(20, () => constantPool.AddConstantPackage(new ConstantPackage(reader.ReadUShort())));
            Action createConstant;

            for (int i = 0; i < constantPoolCount; i++)
            {
                if (tagDictionary.TryGetValue(reader.ReadByte(), out createConstant))
                {
                    createConstant.Invoke();
                }
                else
                {
                    throw new KeyNotFoundException("Constant type not recognized");
                }
            }
            return(constantPool);
        }
Exemplo n.º 3
0
        public static Operand Parse(BytecodeReader reader, OpcodeType parentType)
        {
            uint token0 = reader.ReadUInt32();

            if (token0 == 0)
            {
                return(null);
            }

            var operand = new Operand(parentType);

            var numComponents = token0.DecodeValue <OperandNumComponents>(0, 1);

            switch (numComponents)
            {
            case OperandNumComponents.Zero:
            {
                operand.NumComponents = 0;
                break;
            }

            case OperandNumComponents.One:
            {
                operand.NumComponents = 1;
                break;
            }

            case OperandNumComponents.Four:
            {
                operand.NumComponents = 4;
                operand.SelectionMode = token0.DecodeValue <Operand4ComponentSelectionMode>(2, 3);
                switch (operand.SelectionMode)
                {
                case Operand4ComponentSelectionMode.Mask:
                {
                    operand.ComponentMask = token0.DecodeValue <ComponentMask>(4, 7);
                    break;
                }

                case Operand4ComponentSelectionMode.Swizzle:
                {
                    var swizzle = token0.DecodeValue(4, 11);
                    Func <uint, byte, Operand4ComponentName> swizzleDecoder = (s, i) =>
                                                                              (Operand4ComponentName)((s >> (i * 2)) & 3);
                    operand.Swizzles[0] = swizzleDecoder(swizzle, 0);
                    operand.Swizzles[1] = swizzleDecoder(swizzle, 1);
                    operand.Swizzles[2] = swizzleDecoder(swizzle, 2);
                    operand.Swizzles[3] = swizzleDecoder(swizzle, 3);
                    break;
                }

                case Operand4ComponentSelectionMode.Select1:
                {
                    var swizzle = token0.DecodeValue <Operand4ComponentName>(4, 5);
                    operand.Swizzles[0] = operand.Swizzles[1] = operand.Swizzles[2] = operand.Swizzles[3] = swizzle;
                    break;
                }

                default:
                {
                    throw new ParseException("Unrecognized selection method: " + operand.SelectionMode);
                }
                }
                break;
            }

            case OperandNumComponents.N:
            {
                throw new ParseException("OperandNumComponents.N is not currently supported.");
            }
            }

            operand.OperandType    = token0.DecodeValue <OperandType>(12, 19);
            operand.IndexDimension = token0.DecodeValue <OperandIndexDimension>(20, 21);

            operand.IsExtended = token0.DecodeValue(31, 31) == 1;
            if (operand.IsExtended)
            {
                ReadExtendedOperand(operand, reader);
            }

            Func <uint, byte, OperandIndexRepresentation> indexRepresentationDecoder = (t, i) =>
                                                                                       (OperandIndexRepresentation)t.DecodeValue((byte)(22 + (i * 3)), (byte)(22 + (i * 3) + 2));

            for (byte i = 0; i < (byte)operand.IndexDimension; i++)
            {
                operand.Indices[i] = new OperandIndex();

                var indexRepresentation = indexRepresentationDecoder(token0, i);
                operand.Indices[i].Representation = indexRepresentation;

                switch (indexRepresentation)
                {
                case OperandIndexRepresentation.Immediate32:
                    operand.Indices[i].Value = reader.ReadUInt32();
                    break;

                case OperandIndexRepresentation.Immediate64:
                    operand.Indices[i].Value = reader.ReadUInt64();
                    goto default;

                case OperandIndexRepresentation.Relative:
                    operand.Indices[i].Register = Parse(reader, parentType);
                    break;

                case OperandIndexRepresentation.Immediate32PlusRelative:
                    operand.Indices[i].Value = reader.ReadUInt32();
                    goto case OperandIndexRepresentation.Relative;

                case OperandIndexRepresentation.Immediate64PlusRelative:
                    operand.Indices[i].Value = reader.ReadUInt64();
                    goto case OperandIndexRepresentation.Relative;

                default:
                    throw new ParseException("Unrecognised index representation: " + indexRepresentation);
                }
            }

            var numberType = parentType.GetNumberType();

            switch (operand.OperandType)
            {
            case OperandType.Immediate32:
            {
                var immediateValues = new Number4();
                for (var i = 0; i < operand.NumComponents; i++)
                {
                    immediateValues.SetNumber(i, Number.Parse(reader));
                }
                operand.ImmediateValues = immediateValues;
                break;
            }

            case OperandType.Immediate64:
            {
                var immediateValues = new Number4();
                for (var i = 0; i < operand.NumComponents; i++)
                {
                    immediateValues.SetDouble(i, reader.ReadDouble());
                }
                operand.ImmediateValues = immediateValues;
                break;
            }
            }

            return(operand);
        }