Exemplo n.º 1
0
        public static void WriteParameterReference(ITextOutput writer, MetadataReader metadata, MethodDefinitionHandle handle, int sequence)
        {
            var methodDefinition = metadata.GetMethodDefinition(handle);
            var signature        = methodDefinition.DecodeSignature(new FullTypeNameSignatureDecoder(metadata), default);
            var parameters       = methodDefinition.GetParameters().Select(p => metadata.GetParameter(p)).ToArray();
            var signatureHeader  = signature.Header;
            int index            = sequence;

            if (signatureHeader.IsInstance && signature.ParameterTypes.Length == parameters.Length)
            {
                index--;
            }
            if (index < 0 || index >= parameters.Length)
            {
                writer.WriteLocalReference(sequence.ToString(), "param_" + index);
            }
            else
            {
                var param = parameters[index];
                if (param.Name.IsNil)
                {
                    writer.WriteLocalReference(sequence.ToString(), "param_" + index);
                }
                else
                {
                    writer.WriteLocalReference(Escape(metadata.GetString(param.Name)), "param_" + index);
                }
            }
        }
Exemplo n.º 2
0
        public override void WriteIdentifier(Identifier identifier)
        {
            if (identifier.IsVerbatim || CSharpOutputVisitor.IsKeyword(identifier.Name, identifier))
            {
                output.Write('@');
            }

            var    definition = GetCurrentDefinition();
            string name       = TextWriterTokenWriter.EscapeIdentifier(identifier.Name);

            switch (definition)
            {
            case IType t:
                output.WriteReference(t, name, true);
                return;

            case IMember m:
                output.WriteReference(m, name, true);
                return;
            }

            var member = GetCurrentMemberReference();

            switch (member)
            {
            case IType t:
                output.WriteReference(t, name, false);
                return;

            case IMember m:
                output.WriteReference(m, name, false);
                return;
            }

            var localDefinition = GetCurrentLocalDefinition();

            if (localDefinition != null)
            {
                output.WriteLocalReference(name, localDefinition, isDefinition: true);
                return;
            }

            var localRef = GetCurrentLocalReference();

            if (localRef != null)
            {
                output.WriteLocalReference(name, localRef);
                return;
            }

            if (firstUsingDeclaration && !lastUsingDeclaration)
            {
                output.MarkFoldStart(defaultCollapsed: !settings.ExpandUsingDeclarations);
                firstUsingDeclaration = false;
            }

            output.Write(name);
        }
Exemplo n.º 3
0
        void DisassembleLocalsBlock(MethodDefinitionHandle method, MethodBodyBlock body)
        {
            if (body.LocalSignature.IsNil)
            {
                return;
            }
            output.Write(".locals");
            WriteMetadataToken(body.LocalSignature, spaceBefore: true);
            if (body.LocalVariablesInitialized)
            {
                output.Write(" init");
            }
            var blob      = metadata.GetStandaloneSignature(body.LocalSignature);
            var signature = ImmutableArray <Action <ILNameSyntax> > .Empty;

            try
            {
                if (blob.GetKind() == StandaloneSignatureKind.LocalVariables)
                {
                    signature = blob.DecodeLocalSignature(signatureDecoder, genericContext);
                }
                else
                {
                    output.Write(" /* wrong signature kind */");
                }
            }
            catch (BadImageFormatException ex)
            {
                output.Write($" /* {ex.Message} */");
            }
            output.Write(' ');
            output.WriteLine("(");
            output.Indent();
            int index = 0;

            foreach (var v in signature)
            {
                output.WriteLocalReference("[" + index + "]", "loc_" + index, isDefinition: true);
                output.Write(' ');
                v(ILNameSyntax.TypeName);
                if (DebugInfo != null && DebugInfo.TryGetName(method, index, out var name))
                {
                    output.Write(" " + DisassemblerHelpers.Escape(name));
                }
                if (index + 1 < signature.Length)
                {
                    output.Write(',');
                }
                output.WriteLine();
                index++;
            }
            output.Unindent();
            output.WriteLine(")");
        }
Exemplo n.º 4
0
 public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
 {
     WriteILRange(output, options);
     output.Write(OpCode);
     output.Write(' ');
     output.WriteLocalReference(TargetLabel, (object)targetBlock ?? TargetILOffset);
 }
Exemplo n.º 5
0
 public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
 {
     ILRange.WriteTo(output, options);
     output.Write("Block ");
     output.WriteLocalReference(Label, this, isDefinition: true);
     if (Kind != BlockKind.ControlFlow)
     {
         output.Write($" ({Kind})");
     }
     if (Parent is BlockContainer)
     {
         output.Write(" (incoming: {0})", IncomingEdgeCount);
     }
     output.Write(' ');
     output.MarkFoldStart("{...}");
     output.WriteLine("{");
     output.Indent();
     foreach (var inst in Instructions)
     {
         inst.WriteTo(output, options);
         output.WriteLine();
     }
     if (finalInstruction.OpCode != OpCode.Nop)
     {
         output.Write("final: ");
         finalInstruction.WriteTo(output, options);
         output.WriteLine();
     }
     output.Unindent();
     output.Write("}");
     output.MarkFoldEnd();
 }
Exemplo n.º 6
0
 public static void WriteOffsetReference(ITextOutput writer, int?offset)
 {
     if (offset == null)
     {
         writer.Write("null");
     }
     else
     {
         writer.WriteLocalReference(OffsetToString(offset.Value), offset);
     }
 }
Exemplo n.º 7
0
Arquivo: Leave.cs Projeto: zz110/ILSpy
 public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
 {
     WriteILRange(output, options);
     output.Write(OpCode);
     if (targetContainer != null)
     {
         output.Write(' ');
         output.WriteLocalReference(TargetLabel, targetContainer);
         output.Write(" (");
         value.WriteTo(output, options);
         output.Write(')');
     }
 }
Exemplo n.º 8
0
 public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
 {
     WriteILRange(output, options);
     output.Write("catch ");
     if (variable != null)
     {
         output.WriteLocalReference(variable.Name, variable, isDefinition: true);
         output.Write(" : ");
         Disassembler.DisassemblerHelpers.WriteOperand(output, variable.Type);
     }
     output.Write(" when (");
     filter.WriteTo(output, options);
     output.Write(')');
     output.Write(' ');
     body.WriteTo(output, options);
 }
Exemplo n.º 9
0
        public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
        {
            WriteILRange(output, options);
            output.WriteLocalReference("case", this, isDefinition: true);
            output.Write(' ');
            if (HasNullLabel)
            {
                output.Write("null");
                if (!Labels.IsEmpty)
                {
                    output.Write(", ");
                    output.Write(Labels.ToString());
                }
            }
            else
            {
                output.Write(Labels.ToString());
            }
            output.Write(": ");

            body.WriteTo(output, options);
        }
Exemplo n.º 10
0
 public static void WriteVariableReference(ITextOutput writer, MetadataReader metadata, MethodDefinitionHandle handle, int index)
 {
     writer.WriteLocalReference(index.ToString(), "loc_" + index);
 }
Exemplo n.º 11
0
        protected virtual void WriteInstruction(ITextOutput output, MetadataReader metadata, MethodDefinitionHandle methodDefinition, ref BlobReader blob)
        {
            int offset = blob.Offset;

            if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count)
            {
                var sp = sequencePoints[nextSequencePointIndex];
                if (sp.Offset <= offset)
                {
                    output.Write("// sequence point: ");
                    if (sp.Offset != offset)
                    {
                        output.Write("!! at " + DisassemblerHelpers.OffsetToString(sp.Offset) + " !!");
                    }
                    if (sp.IsHidden)
                    {
                        output.WriteLine("hidden");
                    }
                    else
                    {
                        output.WriteLine($"(line {sp.StartLine}, col {sp.StartColumn}) to (line {sp.EndLine}, col {sp.EndColumn}) in {sp.DocumentUrl}");
                    }
                    nextSequencePointIndex++;
                }
            }
            ILOpCode opCode = ILParser.DecodeOpCode(ref blob);

            output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true);
            output.Write(": ");
            if (opCode.IsDefined())
            {
                output.WriteReference(new OpCodeInfo(opCode, opCode.GetDisplayName()));
                switch (opCode.GetOperandType())
                {
                case OperandType.BrTarget:
                case OperandType.ShortBrTarget:
                    output.Write(' ');
                    int targetOffset = ILParser.DecodeBranchTarget(ref blob, opCode);
                    output.WriteLocalReference($"IL_{targetOffset:x4}", targetOffset);
                    break;

                case OperandType.Field:
                case OperandType.Method:
                case OperandType.Sig:
                case OperandType.Type:
                    output.Write(' ');
                    int          metadataToken = blob.ReadInt32();
                    EntityHandle?handle        = MetadataTokenHelpers.TryAsEntityHandle(metadataToken);
                    try {
                        handle?.WriteTo(module, output, genericContext);
                    } catch (BadImageFormatException) {
                        handle = null;
                    }
                    WriteMetadataToken(handle, metadataToken, spaceBefore: true);
                    break;

                case OperandType.Tok:
                    output.Write(' ');
                    metadataToken = blob.ReadInt32();
                    handle        = MetadataTokenHelpers.TryAsEntityHandle(metadataToken);
                    switch (handle?.Kind)
                    {
                    case HandleKind.MemberReference:
                        switch (metadata.GetMemberReference((MemberReferenceHandle)handle).GetKind())
                        {
                        case MemberReferenceKind.Method:
                            output.Write("method ");
                            break;

                        case MemberReferenceKind.Field:
                            output.Write("field ");
                            break;
                        }
                        break;

                    case HandleKind.FieldDefinition:
                        output.Write("field ");
                        break;

                    case HandleKind.MethodDefinition:
                        output.Write("method ");
                        break;
                    }
                    try {
                        handle?.WriteTo(module, output, genericContext);
                    } catch (BadImageFormatException) {
                        handle = null;
                    }
                    WriteMetadataToken(handle, metadataToken, spaceBefore: true);
                    break;

                case OperandType.ShortI:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadSByte());
                    break;

                case OperandType.I:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadInt32());
                    break;

                case OperandType.I8:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadInt64());
                    break;

                case OperandType.ShortR:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadSingle());
                    break;

                case OperandType.R:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadDouble());
                    break;

                case OperandType.String:
                    metadataToken = blob.ReadInt32();
                    output.Write(' ');
                    UserStringHandle?userString;
                    string           text;
                    try {
                        userString = MetadataTokens.UserStringHandle(metadataToken);
                        text       = metadata.GetUserString(userString.Value);
                    } catch (BadImageFormatException) {
                        userString = null;
                        text       = null;
                    }
                    if (userString != null)
                    {
                        DisassemblerHelpers.WriteOperand(output, text);
                    }
                    WriteMetadataToken(userString, metadataToken, spaceBefore: true);
                    break;

                case OperandType.Switch:
                    int[] targets = ILParser.DecodeSwitchTargets(ref blob);
                    output.Write(" (");
                    for (int i = 0; i < targets.Length; i++)
                    {
                        if (i > 0)
                        {
                            output.Write(", ");
                        }
                        output.WriteLocalReference($"IL_{targets[i]:x4}", targets[i]);
                    }
                    output.Write(")");
                    break;

                case OperandType.Variable:
                    output.Write(' ');
                    int index = blob.ReadUInt16();
                    if (opCode == ILOpCode.Ldloc || opCode == ILOpCode.Ldloca || opCode == ILOpCode.Stloc)
                    {
                        DisassemblerHelpers.WriteVariableReference(output, metadata, methodDefinition, index);
                    }
                    else
                    {
                        DisassemblerHelpers.WriteParameterReference(output, metadata, methodDefinition, index);
                    }
                    break;

                case OperandType.ShortVariable:
                    output.Write(' ');
                    index = blob.ReadByte();
                    if (opCode == ILOpCode.Ldloc_s || opCode == ILOpCode.Ldloca_s || opCode == ILOpCode.Stloc_s)
                    {
                        DisassemblerHelpers.WriteVariableReference(output, metadata, methodDefinition, index);
                    }
                    else
                    {
                        DisassemblerHelpers.WriteParameterReference(output, metadata, methodDefinition, index);
                    }
                    break;
                }
            }
            else
            {
                ushort opCodeValue = (ushort)opCode;
                if (opCodeValue > 0xFF)
                {
                    // split 16-bit value into two emitbyte directives
                    output.WriteLine($".emitbyte 0x{(byte)(opCodeValue >> 8):x}");
                    // add label
                    output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset + 1), offset + 1, isDefinition: true);
                    output.Write(": ");
                    output.Write($".emitbyte 0x{(byte)(opCodeValue & 0xFF):x}");
                }
                else
                {
                    output.Write($".emitbyte 0x{(byte)opCodeValue:x}");
                }
            }
            output.WriteLine();
        }
Exemplo n.º 12
0
 internal void WriteTo(ITextOutput output)
 {
     output.WriteLocalReference(this.Name, this);
 }
Exemplo n.º 13
0
        internal void WriteDefinitionTo(ITextOutput output)
        {
            switch (Kind)
            {
            case VariableKind.Local:
                output.Write("local ");
                break;

            case VariableKind.PinnedLocal:
                output.Write("pinned local ");
                break;

            case VariableKind.Parameter:
                output.Write("param ");
                break;

            case VariableKind.Exception:
                output.Write("exception ");
                break;

            case VariableKind.StackSlot:
                output.Write("stack ");
                break;

            case VariableKind.InitializerTarget:
                output.Write("initializer ");
                break;

            case VariableKind.ForeachLocal:
                output.Write("foreach ");
                break;

            case VariableKind.UsingLocal:
                output.Write("using ");
                break;

            case VariableKind.NamedArgument:
                output.Write("named_arg ");
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            output.WriteLocalReference(this.Name, this, isDefinition: true);
            output.Write(" : ");
            Type.WriteTo(output);
            output.Write('(');
            if (Kind == VariableKind.Parameter || Kind == VariableKind.Local || Kind == VariableKind.PinnedLocal)
            {
                output.Write("Index={0}, ", Index);
            }
            output.Write("LoadCount={0}, AddressCount={1}, StoreCount={2})", LoadCount, AddressCount, StoreCount);
            if (hasInitialValue && Kind != VariableKind.Parameter)
            {
                output.Write(" init");
            }
            if (CaptureScope != null)
            {
                output.Write(" captured in " + CaptureScope.EntryPoint.Label);
            }
            if (StateMachineField != null)
            {
                output.Write(" from state-machine");
            }
        }
Exemplo n.º 14
0
 public void WriteLocalReference(string text, object reference, bool isDefinition = false)
 {
     actions.Add(target => target.WriteLocalReference(text, reference, isDefinition));
 }