예제 #1
0
        public void WriteToken(string token)
        {
            // Attach member reference to token only if there's no identifier in the current node.
            IMemberRef memberRef = GetCurrentMemberReference();
            var        node      = nodeStack.Peek();

            if (memberRef != null && HasNoIdentifier(node))
            {
                output.WriteReference(token, memberRef);
            }
            else if (CSharpOutputVisitor.IsKeyword(token, node))
            {
                output.WriteKeyword(token);
            }
            else if (node is PrimitiveExpression)
            {
                output.WriteLiteral(token);
            }
            else
            {
                output.Write(token);
            }
        }
		public static void WriteOperand(ITextOutput writer, object operand)
		{
			if (operand == null)
				throw new ArgumentNullException("operand");
			
			Instruction targetInstruction = operand as Instruction;
			if (targetInstruction != null) {
				WriteOffsetReference(writer, targetInstruction);
				return;
			}
			
			Instruction[] targetInstructions = operand as Instruction[];
			if (targetInstructions != null) {
				WriteLabelList(writer, targetInstructions);
				return;
			}
			
			Local local = operand as Local;
			if (local != null) {
				if (string.IsNullOrEmpty(local.Name))
					writer.WriteReference("[" + local.Index.ToString() + "]", local, true);
				else
					writer.WriteReference(Escape(local.Name), local, true);
				return;
			}
			
			Parameter param = operand as Parameter;
			if (param != null) {
				if (string.IsNullOrEmpty(param.Name))
					writer.WriteReference("[" + param.Index.ToString() + "]", param, true);
				else
					writer.WriteReference(Escape(param.Name), param, true);
				return;
			}
			
			IMethod methodRef = operand as IMethod;
			if (methodRef != null && dnlibExtensions.IsMethod(methodRef)) {
				methodRef.WriteTo(writer);
				writer.WriteComment(" // 0x" + methodRef.MDToken.Raw.ToString("x8"));
				return;
			}
			
			ITypeDefOrRef typeRef = operand as ITypeDefOrRef;
			if (typeRef != null) {
				typeRef.WriteTo(writer, ILNameSyntax.TypeName);
				writer.WriteComment(" // 0x" + typeRef.MDToken.Raw.ToString("x8"));
				return;
			}

			IField fieldRef = operand as IField;
			if (fieldRef != null && dnlibExtensions.IsField(fieldRef)) {
				fieldRef.WriteTo(writer);
				writer.WriteComment(" // 0x" + fieldRef.MDToken.Raw.ToString("x8"));
				return;
			}
			
			string s = operand as string;
			if (s != null) {
				writer.WriteLiteral("\"" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(s) + "\"");
			} else if (operand is char) {
				writer.WriteLiteral(((int)(char)operand).ToString());
			} else if (operand is float) {
				float val = (float)operand;
				if (val == 0) {
					if (1 / val == float.NegativeInfinity) {
						// negative zero is a special case
						writer.WriteLiteral("-");
					}
					writer.WriteLiteral("0.0");
				} else if (float.IsInfinity(val) || float.IsNaN(val)) {
					byte[] data = BitConverter.GetBytes(val);
					writer.Write('(');
					for (int i = 0; i < data.Length; i++) {
						if (i > 0)
							writer.WriteLiteral(" ");
						writer.WriteLiteral(data[i].ToString("X2"));
					}
					writer.Write(')');
				} else {
					writer.WriteLiteral(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
				}
			} else if (operand is double) {
				double val = (double)operand;
				if (val == 0) {
					if (1 / val == double.NegativeInfinity) {
						// negative zero is a special case
						writer.WriteLiteral("-");
					}
					writer.WriteLiteral("0.0");
				} else if (double.IsInfinity(val) || double.IsNaN(val)) {
					byte[] data = BitConverter.GetBytes(val);
					writer.Write('(');
					for (int i = 0; i < data.Length; i++) {
						if (i > 0)
							writer.WriteLiteral(" ");
						writer.WriteLiteral(data[i].ToString("X2"));
					}
					writer.Write(')');
				} else {
					writer.WriteLiteral(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
				}
			} else if (operand is bool) {
				writer.WriteLiteral((bool)operand ? "true" : "false");
			} else {
				s = ToInvariantCultureString(operand);
				writer.WriteLiteral(s);
			}
		}
예제 #3
0
        public static void WriteOperand(ITextOutput writer, object operand)
        {
            if (operand == null)
            {
                throw new ArgumentNullException("operand");
            }

            Instruction targetInstruction = operand as Instruction;

            if (targetInstruction != null)
            {
                WriteOffsetReference(writer, targetInstruction);
                return;
            }

            Instruction[] targetInstructions = operand as Instruction[];
            if (targetInstructions != null)
            {
                WriteLabelList(writer, targetInstructions);
                return;
            }

            Local local = operand as Local;

            if (local != null)
            {
                if (string.IsNullOrEmpty(local.Name))
                {
                    writer.WriteReference("[" + local.Index.ToString() + "]", local, true);
                }
                else
                {
                    writer.WriteReference(Escape(local.Name), local, true);
                }
                return;
            }

            Parameter param = operand as Parameter;

            if (param != null)
            {
                if (string.IsNullOrEmpty(param.Name))
                {
                    writer.WriteReference("[" + param.Index.ToString() + "]", param, true);
                }
                else
                {
                    writer.WriteReference(Escape(param.Name), param, true);
                }
                return;
            }

            IMethod methodRef = operand as IMethod;

            if (methodRef != null && dnlibExtensions.IsMethod(methodRef))
            {
                methodRef.WriteTo(writer);
                writer.WriteComment(" // 0x" + methodRef.MDToken.Raw.ToString("x8"));
                return;
            }

            ITypeDefOrRef typeRef = operand as ITypeDefOrRef;

            if (typeRef != null)
            {
                typeRef.WriteTo(writer, ILNameSyntax.TypeName);
                writer.WriteComment(" // 0x" + typeRef.MDToken.Raw.ToString("x8"));
                return;
            }

            IField fieldRef = operand as IField;

            if (fieldRef != null && dnlibExtensions.IsField(fieldRef))
            {
                fieldRef.WriteTo(writer);
                writer.WriteComment(" // 0x" + fieldRef.MDToken.Raw.ToString("x8"));
                return;
            }

            string s = operand as string;

            if (s != null)
            {
                writer.WriteLiteral("\"" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(s) + "\"");
            }
            else if (operand is char)
            {
                writer.WriteLiteral(((int)(char)operand).ToString());
            }
            else if (operand is float)
            {
                float val = (float)operand;
                if (val == 0)
                {
                    if (1 / val == float.NegativeInfinity)
                    {
                        // negative zero is a special case
                        writer.WriteLiteral("-");
                    }
                    writer.WriteLiteral("0.0");
                }
                else if (float.IsInfinity(val) || float.IsNaN(val))
                {
                    byte[] data = BitConverter.GetBytes(val);
                    writer.Write('(');
                    for (int i = 0; i < data.Length; i++)
                    {
                        if (i > 0)
                        {
                            writer.WriteLiteral(" ");
                        }
                        writer.WriteLiteral(data[i].ToString("X2"));
                    }
                    writer.Write(')');
                }
                else
                {
                    writer.WriteLiteral(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
                }
            }
            else if (operand is double)
            {
                double val = (double)operand;
                if (val == 0)
                {
                    if (1 / val == double.NegativeInfinity)
                    {
                        // negative zero is a special case
                        writer.WriteLiteral("-");
                    }
                    writer.WriteLiteral("0.0");
                }
                else if (double.IsInfinity(val) || double.IsNaN(val))
                {
                    byte[] data = BitConverter.GetBytes(val);
                    writer.Write('(');
                    for (int i = 0; i < data.Length; i++)
                    {
                        if (i > 0)
                        {
                            writer.WriteLiteral(" ");
                        }
                        writer.WriteLiteral(data[i].ToString("X2"));
                    }
                    writer.Write(')');
                }
                else
                {
                    writer.WriteLiteral(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
                }
            }
            else if (operand is bool)
            {
                writer.WriteLiteral((bool)operand ? "true" : "false");
            }
            else
            {
                s = ToInvariantCultureString(operand);
                writer.WriteLiteral(s);
            }
        }
        public void Disassemble(MethodDef method, CilBody body, MemberMapping methodMapping)
        {
            // start writing IL code
            output.WriteLineComment("// Method Token is 0x{0:x8}", method.MDToken.Raw);
            output.WriteLineComment("// Method begins at RVA 0x{0:x}", method.RVA);
            output.WriteLineComment("// Code size {0} (0x{0:x})", body.GetCodeSize());
            output.WriteKeyword(".maxstack ");
            output.WriteLiteral(body.MaxStack.ToString());
            output.WriteLine();
            if (method.DeclaringType.Module.Assembly != null && method.DeclaringType.Module.EntryPoint == method)
            {
                output.WriteKeyword(".entrypoint");
                output.WriteLine();
            }

            if (method.Body.HasVariables)
            {
                output.WriteKeyword(".locals ");
                if (method.Body.InitLocals)
                {
                    output.WriteKeyword("init ");
                }
                output.WriteLine("(");
                output.Indent();
                foreach (var v in method.Body.Variables)
                {
                    output.WriteDefinition("[" + v.Index + "]", v, true);
                    output.Write(" ");
                    v.Type.WriteTo(output);
                    if (!string.IsNullOrEmpty(v.Name))
                    {
                        output.Write(' ');
                        output.Write(DisassemblerHelpers.Escape(v.Name));
                    }
                    if (v.Index + 1 < method.Body.Variables.Count)
                    {
                        output.Write(',');
                    }
                    output.WriteLine();
                }
                output.Unindent();
                output.WriteLine(")");
            }
            output.WriteLine();

            if (detectControlStructure && body.Instructions.Count > 0)
            {
                Instruction inst          = body.Instructions[0];
                var         branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(method, body, new ILStructure(body), branchTargets, ref inst, methodMapping, method.Body.GetCodeSize());
            }
            else
            {
                foreach (var inst in method.Body.Instructions)
                {
                    var startLocation = output.Location;
                    inst.WriteTo(method, body, output);

                    if (methodMapping != null)
                    {
                        var next = inst.GetNext(body);
                        // add IL code mappings - used in debugger
                        methodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            StartLocation       = output.Location,
                            EndLocation         = output.Location,
                            ILInstructionOffset = new ILRange {
                                From = inst.Offset, To = next == null ? method.Body.GetCodeSize() : next.Offset
                            },
                            MemberMapping = methodMapping
                        });
                    }

                    output.WriteLine();
                }
                if (method.Body.HasExceptionHandlers)
                {
                    output.WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        eh.WriteTo(output);
                        output.WriteLine();
                    }
                }
            }
        }