Пример #1
0
        public override MetadataStream CreateStream()
        {
            using (var stream = new MemoryStream())
            {
                var writer = new BinaryStreamWriter(stream);
                writer.WriteByte(0);

                var processedSignatures = new HashSet <BlobSignature>();
                var agenda = new Queue <BlobSignature>(_signatureOffsetMapping.Keys);

                while (agenda.Count > 0)
                {
                    var signature = agenda.Dequeue();
                    if (processedSignatures.Add(signature))
                    {
                        writer.WriteCompressedUInt32(signature.GetPhysicalLength());

                        int count = _signatureOffsetMapping.Count;
                        signature.Write(_parentBuffer, writer);

                        // TODO: find more efficient way of adding newly created signatures to the queue.
                        if (count != _signatureOffsetMapping.Count)
                        {
                            foreach (var sig in _signatureOffsetMapping.Keys)
                            {
                                agenda.Enqueue(sig);
                            }
                        }
                    }
                }

                writer.WriteZeroes((int)(FileSegment.Align(_length, 4) - _length));
                return(new BlobStream(new MemoryStreamReader(stream.ToArray())));
            }
        }
Пример #2
0
        public override MetadataStream CreateStream()
        {
            using (var stream = new MemoryStream())
            {
                var writer = new BinaryStreamWriter(stream);
                writer.WriteByte(0);

                foreach (var signature in _signatureOffsetMapping.Keys)
                {
                    writer.WriteCompressedUInt32(signature.GetPhysicalLength(_parentBuffer));
                    signature.Write(_parentBuffer, writer);
                }

                writer.WriteZeroes((int)(FileSegment.Align(_length, 4) - _length));
                return(new BlobStream(new MemoryStreamReader(stream.ToArray())));
            }
        }
Пример #3
0
        public override MetadataStream CreateStream()
        {
            using (var stream = new MemoryStream())
            {
                var writer = new BinaryStreamWriter(stream);
                writer.WriteByte(0);

                foreach (string value in _stringOffsetMapping.Keys)
                {
                    writer.WriteBytes(Encoding.UTF8.GetBytes(value));
                    writer.WriteByte(0);
                }

                writer.WriteZeroes((int)(FileSegment.Align(_length, 4) - _length));

                return(new StringStream(new MemoryStreamReader(stream.ToArray())));
            }
        }
Пример #4
0
        private int GetOperandSize()
        {
            switch (OpCode.OperandType)
            {
            case ByteCodeOperandType.None:
                return(0);

            case ByteCodeOperandType.Byte:
            case ByteCodeOperandType.LocalIndex:
            case ByteCodeOperandType.PrimitiveType:
            case ByteCodeOperandType.ConstantIndex:
                return(1);

            case ByteCodeOperandType.Short:
            case ByteCodeOperandType.LocalConst:
            case ByteCodeOperandType.BranchOffset:
            case ByteCodeOperandType.FieldIndex:
            case ByteCodeOperandType.MethodIndex:
            case ByteCodeOperandType.ClassIndex:
                return(2);

            case ByteCodeOperandType.WideConstantIndex:
            case ByteCodeOperandType.WideBranchOffset:
            case ByteCodeOperandType.WideIndexCountZero:
            case ByteCodeOperandType.WideIndexByte:
            case ByteCodeOperandType.DynamicIndex:
                return(4);

            case ByteCodeOperandType.TableSwitch:
            {
                int padding = (int)(FileSegment.Align((uint)Offset, 4) - Offset) - 1;
                return(padding + (3 + ((TableSwitch)Operand).Offsets.Count) * 4);
            }

            case ByteCodeOperandType.LookupSwitch:
            {
                int padding = (int)(FileSegment.Align((uint)Offset, 4) - Offset) - 1;
                return(padding + (2 + ((LookupSwitch)Operand).Table.Count * 2) * 4);
            }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #5
0
        private object ReadRawOperand(ByteOpCode opcode)
        {
            switch (opcode.OperandType)
            {
            case ByteCodeOperandType.None:
                return(null);

            case ByteCodeOperandType.Byte:
            case ByteCodeOperandType.ConstantIndex:
            case ByteCodeOperandType.LocalIndex:
            case ByteCodeOperandType.PrimitiveType:
                return(_reader.ReadByte());

            case ByteCodeOperandType.Short:
            case ByteCodeOperandType.WideConstantIndex:
            case ByteCodeOperandType.BranchOffset:
            case ByteCodeOperandType.LocalConst:
            case ByteCodeOperandType.FieldIndex:
            case ByteCodeOperandType.MethodIndex:
            case ByteCodeOperandType.ClassIndex:
                return(_reader.ReadInt16());

            case ByteCodeOperandType.TableSwitch:
                _reader.Position = FileSegment.Align((uint)_reader.Position, 4);
                return(TableSwitch.FromReader(_reader));

            case ByteCodeOperandType.LookupSwitch:
                _reader.Position = FileSegment.Align((uint)_reader.Position, 4);
                return(LookupSwitch.FromReader(_reader));

            case ByteCodeOperandType.WideIndexCountZero:
            case ByteCodeOperandType.WideIndexByte:
            case ByteCodeOperandType.WideBranchOffset:
            case ByteCodeOperandType.DynamicIndex:
                return(_reader.ReadInt32());

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #6
0
        private void WriteOperand(ByteCodeInstruction instruction)
        {
            switch (instruction.OpCode.OperandType)
            {
            case ByteCodeOperandType.None:
                break;

            case ByteCodeOperandType.Byte:
            case ByteCodeOperandType.LocalIndex:
            case ByteCodeOperandType.PrimitiveType:
                _writer.Write(Convert.ToByte(instruction.Operand));
                break;

            case ByteCodeOperandType.Short:
            case ByteCodeOperandType.LocalConst:
                _writer.Write(Convert.ToInt16(instruction.Operand));
                break;

            case ByteCodeOperandType.FieldIndex:
                _writer.Write(instruction.Operand is FieldReference fieldRef
                        ? (ushort)OperandBuilder.GetFieldIndex(fieldRef)
                        : Convert.ToUInt16(instruction.Operand));
                break;

            case ByteCodeOperandType.MethodIndex:
                _writer.Write(instruction.Operand is MethodReference methodRef
                        ? (ushort)OperandBuilder.GetMethodIndex(methodRef)
                        : Convert.ToUInt16(instruction.Operand));
                break;

            case ByteCodeOperandType.ClassIndex:
                _writer.Write(instruction.Operand is ClassReference classRef
                        ? (ushort)OperandBuilder.GetClassIndex(classRef)
                        : Convert.ToUInt16(instruction.Operand));
                break;

            case ByteCodeOperandType.ConstantIndex:
                _writer.Write((byte)OperandBuilder.GetLiteralIndex(instruction.Operand));
                break;

            case ByteCodeOperandType.WideConstantIndex:
                _writer.Write((ushort)OperandBuilder.GetLiteralIndex(instruction.Operand));
                break;

            case ByteCodeOperandType.BranchOffset:
            {
                short relativeOffset;
                if (instruction.Operand is ByteCodeInstruction target)
                {
                    relativeOffset = (short)(target.Offset - instruction.Offset);
                }
                else
                {
                    relativeOffset = Convert.ToInt16(instruction.Operand);
                }

                _writer.Write(relativeOffset);
                break;
            }

            case ByteCodeOperandType.WideBranchOffset:
            {
                int relativeOffset;
                if (instruction.Operand is ByteCodeInstruction target)
                {
                    relativeOffset = (target.Offset - instruction.Offset);
                }
                else
                {
                    relativeOffset = Convert.ToInt32(instruction.Operand);
                }

                _writer.Write(relativeOffset);
                break;
            }

            case ByteCodeOperandType.TableSwitch:
            case ByteCodeOperandType.LookupSwitch:
                _writer.Position = FileSegment.Align((uint)_writer.Position, 4);
                ((ISwitchOperand)instruction.Operand).Write(_writer, instruction.Offset);
                break;

            case ByteCodeOperandType.WideIndexCountZero:
            case ByteCodeOperandType.WideIndexByte:
                _writer.Write(Convert.ToInt32(instruction.Operand));
                break;

            case ByteCodeOperandType.DynamicIndex:
                _writer.Write(instruction.Operand is DynamicInvocation invocation
                        ? OperandBuilder.GetDynamicIndex(invocation) << 16
                        : Convert.ToInt32(instruction.Operand));
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }