示例#1
0
        private void WriteOperand(
            Instruction instruction)
        {
            var opcode      = instruction.OpCode;
            var operandType = opcode.OperandType;

            if (operandType == OperandType.InlineNone)
            {
                return;
            }

            var operand = instruction.Operand;

            if (operand == null)
            {
                throw new ArgumentException();
            }

            switch (operandType)
            {
            case OperandType.InlineSwitch:
            {
                var targets = (Instruction[])operand;
                _writer.WriteByte((Byte)targets.Length);
                var diff = instruction.Offset + opcode.Size + 2 * targets.Length + 1;
                foreach (var item in targets)
                {
                    _writer.WriteInt16((Int16)(GetTargetOffset(item) - diff));
                }
                break;
            }

            case OperandType.ShortInlineBrTarget:
            {
                var target = (Instruction)operand;
                _writer.WriteSByte((SByte)
                                   (GetTargetOffset(target) - (instruction.Offset + opcode.Size + 1)));
                break;
            }

            case OperandType.InlineBrTarget:
            {
                var target = (Instruction)operand;
                _writer.WriteInt16((Int16)
                                   (GetTargetOffset(target) - (instruction.Offset + opcode.Size + 2)));
                break;
            }

            case OperandType.ShortInlineVar:
                _writer.WriteByte((byte)GetVariableIndex((VariableDefinition)operand));
                break;

            case OperandType.ShortInlineArg:
                _writer.WriteByte((byte)GetParameterIndex((ParameterDefinition)operand));
                break;

            case OperandType.InlineVar:
                _writer.WriteInt16((short)GetVariableIndex((VariableDefinition)operand));
                break;

            case OperandType.InlineArg:
                _writer.WriteInt16((short)GetParameterIndex((ParameterDefinition)operand));
                break;

            case OperandType.InlineSig:
                // TODO: implement this properly after finding when such code is generated
                //WriteMetadataToken (GetStandAloneSignature ((CallSite) operand));
                break;

            case OperandType.ShortInlineI:
                if (opcode == OpCodes.Ldc_I4_S)
                {
                    _writer.WriteSByte((SByte)operand);
                }
                else
                {
                    _writer.WriteByte((Byte)operand);
                }
                break;

            case OperandType.InlineI:
                _writer.WriteInt32((Int32)operand);
                break;

            case OperandType.InlineI8:
                _writer.WriteInt64((Int64)operand);
                break;

            case OperandType.ShortInlineR:
                _writer.WriteSingle((Single)operand);
                break;

            case OperandType.InlineR:
                _writer.WriteDouble((Double)operand);
                break;

            case OperandType.InlineString:
                var stringReferenceId = _stringTable.GetOrCreateStringId((String)operand, false);
                _writer.WriteUInt16(stringReferenceId);
                break;

            case OperandType.InlineMethod:
                _writer.WriteUInt16(_context.GetMethodReferenceId((MethodReference)operand));
                break;

            case OperandType.InlineType:
                _writer.WriteUInt16(GetTypeReferenceId((TypeReference)operand));
                break;

            case OperandType.InlineField:
                _writer.WriteUInt16(GetFieldReferenceId((FieldReference)operand));
                break;

            case OperandType.InlineTok:
                _writer.WriteUInt32(GetMetadataToken((IMetadataTokenProvider)operand));
                break;

            default:
                throw new ArgumentException();
            }
        }