refactor .NET-specific CodeProvider code into separate ILCodeProvider class
This commit is contained in:
parent
60d72f91b5
commit
2c0d651756
@ -33,7 +33,7 @@ namespace UniversalEditor.Plugins.Executable.UserInterface.Editors.Executable
|
||||
/// <summary>
|
||||
/// Gets the <see cref="CodeProviders.CSharpCodeProvider" />
|
||||
/// </summary>
|
||||
/// <value>The CS harp.</value>
|
||||
/// <value>The C# code provider.</value>
|
||||
public static CodeProviders.CSharpCodeProvider CSharp { get; } = new CodeProviders.CSharpCodeProvider();
|
||||
|
||||
public abstract string Title { get; }
|
||||
@ -186,290 +186,5 @@ namespace UniversalEditor.Plugins.Executable.UserInterface.Editors.Executable
|
||||
{
|
||||
return GetMethodSignatureInternal(mi);
|
||||
}
|
||||
|
||||
private static BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
|
||||
|
||||
public MethodInfo[] GetMethods(Type type)
|
||||
{
|
||||
MethodInfo[] meths = type.GetMethods(bindingFlags);
|
||||
List<MethodInfo> list = new List<MethodInfo>();
|
||||
for (int j = 0; j < meths.Length; j++)
|
||||
{
|
||||
if (meths[j].IsSpecialName && (meths[j].Name.StartsWith("set_", StringComparison.OrdinalIgnoreCase) || meths[j].Name.StartsWith("get_", StringComparison.OrdinalIgnoreCase)) && (type.GetProperty(meths[j].Name.Substring(4), bindingFlags) != null))
|
||||
{
|
||||
// we can be REASONABLY sure that this is a property setter / getter,
|
||||
// and as we've already gotten all the properties, ignore it
|
||||
continue;
|
||||
}
|
||||
list.Add(meths[j]);
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
public FieldInfo[] GetFields(Type type, out List<string> AutoPropertyNames)
|
||||
{
|
||||
List<FieldInfo> list = new List<FieldInfo>();
|
||||
AutoPropertyNames = new List<string>();
|
||||
|
||||
FieldInfo[] fields = type.GetFields(bindingFlags);
|
||||
for (int j = 0; j < fields.Length; j++)
|
||||
{
|
||||
if (fields[j].Name.StartsWith("<", StringComparison.OrdinalIgnoreCase) && fields[j].Name.Contains(">"))
|
||||
{
|
||||
// might be a backing field
|
||||
int k__backingfield_name_start = fields[j].Name.IndexOf('<');
|
||||
int k__backingfield_name_end = fields[j].Name.IndexOf('>', k__backingfield_name_start);
|
||||
|
||||
string k__backingfield_name = fields[j].Name.Substring(k__backingfield_name_start + 1, k__backingfield_name_end - k__backingfield_name_start - 1);
|
||||
PropertyInfo pi = type.GetProperty(k__backingfield_name, bindingFlags);
|
||||
if (pi != null)
|
||||
{
|
||||
AutoPropertyNames.Add(pi.Name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(fields[j]);
|
||||
}
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
public string GetILOpcodeStr(short opcode)
|
||||
{
|
||||
return GetILOpcodeStr((ILOpcode)opcode);
|
||||
}
|
||||
public string GetILOpcodeStr(ILOpcode opcode)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case ILOpcode.Add: return "add";
|
||||
case ILOpcode.AddOvf: return "add.ovf";
|
||||
case ILOpcode.AddOvfUn: return "add.ovf.un";
|
||||
case ILOpcode.And: return "and";
|
||||
case ILOpcode.ArgList: return "arglist";
|
||||
case ILOpcode.Beq: return "beq <int32 (target)>";
|
||||
case ILOpcode.BeqS: return "beq <int32 (target)>";
|
||||
case ILOpcode.Bge: return "bge <int32 (target)>";
|
||||
case ILOpcode.BgeS: return "bge.s <int8 (target)>";
|
||||
case ILOpcode.BgeUn: return "bge.un <int32 (target)>";
|
||||
case ILOpcode.BgeUnS: return "bge.un.s <int8 (target)>";
|
||||
case ILOpcode.Bgt: return "bgt <int32 (target)>";
|
||||
case ILOpcode.BgtS: return "bgt.s <int8 (target)>";
|
||||
case ILOpcode.BgtUn: return "bgt.un <int32 (target)>";
|
||||
case ILOpcode.BgtUnS: return "bgt.un.s <int8 (target)>";
|
||||
case ILOpcode.Ble: return "ble <int32 (target)>";
|
||||
case ILOpcode.BleS: return "ble.s <int8 (target)>";
|
||||
case ILOpcode.BleUn: return "ble.un <int32 (target)>";
|
||||
case ILOpcode.BleUnS: return "ble.un.s <int8 (target)>";
|
||||
case ILOpcode.Blt: return "blt <int32 (target)>";
|
||||
case ILOpcode.BltS: return "blt.s <int8 (target)>";
|
||||
case ILOpcode.BltUn: return "blt.un <int32 (target)>";
|
||||
case ILOpcode.BltUnS: return "blt.un.s <int8 (target)>";
|
||||
case ILOpcode.BneUn: return "bne.un <int32 (target)>";
|
||||
case ILOpcode.BneUnS: return "bne.un.s <int8 (target)>";
|
||||
case ILOpcode.Box: return "box <typeTok>";
|
||||
case ILOpcode.Br: return "br <int32 (target)>";
|
||||
case ILOpcode.BrS: return "br.s <int8 (target)>";
|
||||
case ILOpcode.Break: return "break";
|
||||
case ILOpcode.BrFalse: return "brfalse <int32 (target)>";
|
||||
case ILOpcode.BrFalseS: return "brfalse.s <int8 (target)>";
|
||||
case ILOpcode.BrTrue: return "brtrue <int32 (target)>";
|
||||
case ILOpcode.BrTrueS: return "brtrue.s <int8 (target)>";
|
||||
case ILOpcode.Call: return "call <method>";
|
||||
case ILOpcode.CallI: return "calli <callsitedescr>";
|
||||
case ILOpcode.CallVirt: return "callvirt <method>";
|
||||
case ILOpcode.CastClass: return "castclass <class>";
|
||||
case ILOpcode.Ceq: return "ceq";
|
||||
case ILOpcode.Cgt: return "cgt";
|
||||
case ILOpcode.CgtUn: return "cgt.un";
|
||||
case ILOpcode.CkFinite: return "ckfinite";
|
||||
case ILOpcode.Clt: return "clt";
|
||||
case ILOpcode.CltUn: return "clt.un";
|
||||
case ILOpcode.Constrained: return "constrained <thisType>";
|
||||
case ILOpcode.ConvI: return "conv.i";
|
||||
case ILOpcode.ConvI1: return "conv.i1";
|
||||
case ILOpcode.ConvI2: return "conv.i2";
|
||||
case ILOpcode.ConvI4: return "conv.i4";
|
||||
case ILOpcode.ConvI8: return "conv.i8";
|
||||
case ILOpcode.ConvOvfI: return "conv.ovf.i";
|
||||
case ILOpcode.ConvOvfIUn: return "conv.ovf.i.un";
|
||||
case ILOpcode.ConvOvfI1: return "conv.ovf.i1";
|
||||
case ILOpcode.ConvOvfI1Un: return "conv.ovf.i1.un";
|
||||
case ILOpcode.ConvOvfI2: return "conv.ovf.i2";
|
||||
case ILOpcode.ConvOvfI2Un: return "conv.ovf.i2.un";
|
||||
case ILOpcode.ConvOvfI4: return "conv.ovf.i4";
|
||||
case ILOpcode.ConvOvfI4Un: return "conv.ovf.i4.un";
|
||||
case ILOpcode.ConvOvfI8: return "conv.ovf.i8";
|
||||
case ILOpcode.ConvOvfI8Un: return "conv.ovf.i8.un";
|
||||
case ILOpcode.ConvOvfU: return "conv.ovf.u";
|
||||
case ILOpcode.ConvOvfUUn: return "conv.ovf.u.un";
|
||||
case ILOpcode.ConvOvfU1: return "conv.ovf.u1";
|
||||
case ILOpcode.ConvOvfU1Un: return "conv.ovf.u1.un";
|
||||
case ILOpcode.ConvOvfU2: return "conv.ovf.u2";
|
||||
case ILOpcode.ConvOvfU2Un: return "conv.ovf.u2.un";
|
||||
case ILOpcode.ConvOvfU4: return "conv.ovf.u4";
|
||||
case ILOpcode.ConvOvfU4Un: return "conv.ovf.u4.un";
|
||||
case ILOpcode.ConvOvfU8: return "conv.ovf.u8";
|
||||
case ILOpcode.ConvOvfU8Un: return "conv.ovf.u8.un";
|
||||
case ILOpcode.ConvRUn: return "conv.r.un";
|
||||
case ILOpcode.ConvR4: return "conv.r4";
|
||||
case ILOpcode.ConvR8: return "conv.r8";
|
||||
case ILOpcode.ConvU: return "conv.u";
|
||||
case ILOpcode.ConvU1: return "conv.u1";
|
||||
case ILOpcode.ConvU2: return "conv.u2";
|
||||
case ILOpcode.ConvU4: return "conv.u4";
|
||||
case ILOpcode.ConvU8: return "conv.u8";
|
||||
case ILOpcode.CpBlk: return "cpblk";
|
||||
case ILOpcode.CpObj: return "cpobj <typeTok>";
|
||||
case ILOpcode.Div: return "div";
|
||||
case ILOpcode.DivUn: return "div.un";
|
||||
case ILOpcode.Dup: return "dup";
|
||||
case ILOpcode.EndFault: return "endfault";
|
||||
case ILOpcode.EndFilter: return "endfilter";
|
||||
// case ILOpcode.EndFinally: return "endfinally"; // same as endfault?
|
||||
case ILOpcode.InitBlk: return "initblk";
|
||||
case ILOpcode.InitObj: return "initobj <typeTok>";
|
||||
case ILOpcode.IsInst: return "isinst <class>";
|
||||
case ILOpcode.Jmp: return "jmp";
|
||||
case ILOpcode.LdArg: return "ldarg <uint16 (num)>";
|
||||
case ILOpcode.LdArg0: return "ldarg.0";
|
||||
case ILOpcode.LdArg1: return "ldarg.1";
|
||||
case ILOpcode.LdArg2: return "ldarg.2";
|
||||
case ILOpcode.LdArg3: return "ldarg.3";
|
||||
case ILOpcode.LdArgS: return "ldarg.s <uint8 (num)>";
|
||||
case ILOpcode.LdArgA: return "ldarg.a <uint16 (num)>";
|
||||
case ILOpcode.LdArgAS: return "ldarg.a.s <uint8 (num)>";
|
||||
case ILOpcode.LdCI4: return "ldc.i4 <int32 (num)>";
|
||||
case ILOpcode.LdCI4_M1: return "ldc.i4.m1";
|
||||
case ILOpcode.LdCI4_0: return "ldc.i4.0";
|
||||
case ILOpcode.LdCI4_1: return "ldc.i4.1";
|
||||
case ILOpcode.LdCI4_2: return "ldc.i4.2";
|
||||
case ILOpcode.LdCI4_3: return "ldc.i4.3";
|
||||
case ILOpcode.LdCI4_4: return "ldc.i4.4";
|
||||
case ILOpcode.LdCI4_5: return "ldc.i4.5";
|
||||
case ILOpcode.LdCI4_6: return "ldc.i4.6";
|
||||
case ILOpcode.LdCI4_7: return "ldc.i4.7";
|
||||
case ILOpcode.LdCI4_8: return "ldc.i4.8";
|
||||
case ILOpcode.LdCI4S: return "ldc.i4.s <int8 (num)>";
|
||||
case ILOpcode.LdCI8: return "ldc.i8 <int64 (num)>";
|
||||
case ILOpcode.LdCR4: return "ldc.r4 <float32 (num)>";
|
||||
case ILOpcode.LdCR8: return "ldc.r8 <float64 (num)>";
|
||||
case ILOpcode.LdElem: return "ldelem <typeTok>";
|
||||
case ILOpcode.LdElemI: return "ldelem.i";
|
||||
case ILOpcode.LdElemI1: return "ldelem.i1";
|
||||
case ILOpcode.LdElemU1: return "ldelem.u1";
|
||||
case ILOpcode.LdElemI2: return "ldelem.i2";
|
||||
case ILOpcode.LdElemU2: return "ldelem.u2";
|
||||
case ILOpcode.LdElemI4: return "ldelem.i4";
|
||||
case ILOpcode.LdElemU4: return "ldelem.u4";
|
||||
case ILOpcode.LdElemI8: return "ldelem.i8";
|
||||
case ILOpcode.LdElemR4: return "ldelem.r4";
|
||||
case ILOpcode.LdElemR8: return "ldelem.r8";
|
||||
case ILOpcode.LdElemRef: return "ldelem.ref";
|
||||
case ILOpcode.LdElemA: return "ldelema <class>";
|
||||
case ILOpcode.LdFld: return "ldfld <field>";
|
||||
case ILOpcode.LdFldA: return "ldflda <field>";
|
||||
case ILOpcode.LdFtn: return "ldftn <method>";
|
||||
case ILOpcode.LdIndI: return "ldind.i";
|
||||
case ILOpcode.LdIndI1: return "ldind.i1";
|
||||
case ILOpcode.LdIndU1: return "ldind.u1";
|
||||
case ILOpcode.LdIndI2: return "ldind.i2";
|
||||
case ILOpcode.LdIndU2: return "ldind.u2";
|
||||
case ILOpcode.LdIndI4: return "ldind.i4";
|
||||
case ILOpcode.LdIndU4: return "ldind.u4";
|
||||
case ILOpcode.LdIndI8: return "ldind.i8";
|
||||
case ILOpcode.LdIndR4: return "ldind.r4";
|
||||
case ILOpcode.LdIndR8: return "ldind.r8";
|
||||
case ILOpcode.LdLen: return "ldlen";
|
||||
case ILOpcode.LdLoc: return "ldloc <uint16 (indx)>";
|
||||
case ILOpcode.LdLoc0: return "ldloc.0";
|
||||
case ILOpcode.LdLoc1: return "ldloc.1";
|
||||
case ILOpcode.LdLoc2: return "ldloc.2";
|
||||
case ILOpcode.LdLoc3: return "ldloc.3";
|
||||
case ILOpcode.LdLocS: return "ldloc.s <uint8 (indx)>";
|
||||
case ILOpcode.LdLocA: return "ldloca <uint16 (indx)>";
|
||||
case ILOpcode.LdLocAS: return "ldloca.s <uint8 (indx)>";
|
||||
case ILOpcode.LdNull: return "ldnull";
|
||||
case ILOpcode.LdObj: return "ldobj <typeTok>";
|
||||
case ILOpcode.LdSFld: return "ldsfld <field>";
|
||||
case ILOpcode.LdSFldA: return "ldsflda <field>";
|
||||
case ILOpcode.LdStr: return "ldstr <string>";
|
||||
case ILOpcode.LdToken: return "ldtoken <token>";
|
||||
case ILOpcode.LdVirtFtn: return "ldvirtftn <method>";
|
||||
case ILOpcode.Leave: return "leave <int32 (target)>";
|
||||
case ILOpcode.LeaveS: return "leave <int8 (target)>";
|
||||
case ILOpcode.LocAlloc: return "localloc";
|
||||
case ILOpcode.MkRefAny: return "mkrefany <class>";
|
||||
case ILOpcode.Mul: return "mul";
|
||||
case ILOpcode.MulOvf: return "mul.ovf";
|
||||
case ILOpcode.MulOvfUn: return "mul.ovf.un";
|
||||
case ILOpcode.Neg: return "neg";
|
||||
case ILOpcode.NewArr: return "newarr <etype>";
|
||||
case ILOpcode.NewObj: return "newobj <ctor>";
|
||||
case ILOpcode.No: return "no.{typecheck, rangecheck, nullcheck}";
|
||||
case ILOpcode.Nop: return "nop";
|
||||
case ILOpcode.Not: return "not";
|
||||
case ILOpcode.Or: return "or";
|
||||
case ILOpcode.Pop: return "pop";
|
||||
case ILOpcode.Readonly: return "readonly.";
|
||||
case ILOpcode.RefAnyType: return "refanytype";
|
||||
case ILOpcode.RefAnyVal: return "refanyval <type>";
|
||||
case ILOpcode.Rem: return "rem";
|
||||
case ILOpcode.RemUn: return "rem.un";
|
||||
case ILOpcode.Ret: return "ret";
|
||||
case ILOpcode.Rethrow: return "rethrow";
|
||||
case ILOpcode.Shl: return "shl";
|
||||
case ILOpcode.Shr: return "shl";
|
||||
case ILOpcode.ShrUn: return "shl";
|
||||
case ILOpcode.SizeOf: return "sizeof <typeTok>";
|
||||
case ILOpcode.StArg: return "starg <uint16 (num)>";
|
||||
case ILOpcode.StArgS: return "starg.s <uint8 (num)>";
|
||||
case ILOpcode.StElem: return "stelem <typeTok>";
|
||||
case ILOpcode.StElemI: return "stelem.i";
|
||||
case ILOpcode.StElemI1: return "stelem.i1";
|
||||
case ILOpcode.StElemI2: return "stelem.i2";
|
||||
case ILOpcode.StElemI4: return "stelem.i4";
|
||||
case ILOpcode.StElemI8: return "stelem.i8";
|
||||
case ILOpcode.StElemR4: return "stelem.r4";
|
||||
case ILOpcode.StElemR8: return "stelem.r8";
|
||||
case ILOpcode.StElemRef: return "stelem.ref";
|
||||
case ILOpcode.StFld: return "stfld <field>";
|
||||
case ILOpcode.StIndI: return "stind.i";
|
||||
case ILOpcode.StIndI1: return "stind.i1";
|
||||
case ILOpcode.StIndI2: return "stind.i2";
|
||||
case ILOpcode.StIndI4: return "stind.i4";
|
||||
case ILOpcode.StIndI8: return "stind.i8";
|
||||
case ILOpcode.StIndR4: return "stind.r4";
|
||||
case ILOpcode.StIndR8: return "stind.r8";
|
||||
case ILOpcode.StIndRef: return "stind.ref";
|
||||
case ILOpcode.StLoc: return "stloc <uint16 (indx)>";
|
||||
case ILOpcode.StLoc0: return "stloc.0";
|
||||
case ILOpcode.StLoc1: return "stloc.1";
|
||||
case ILOpcode.StLoc2: return "stloc.2";
|
||||
case ILOpcode.StLoc3: return "stloc.3";
|
||||
case ILOpcode.StLocS: return "stloc.s <uint8 (indx)>";
|
||||
case ILOpcode.StObj: return "stobj <typeTok>";
|
||||
case ILOpcode.StSFld: return "stsfld <field>";
|
||||
case ILOpcode.Sub: return "sub";
|
||||
case ILOpcode.SubOvf: return "sub.ovf";
|
||||
case ILOpcode.SubOvfUn: return "sub.ovf.un";
|
||||
case ILOpcode.Switch: return "switch <uint32, int32, int32 (t1..tN)>";
|
||||
case ILOpcode.Tail: return "tail.";
|
||||
case ILOpcode.Throw: return "throw";
|
||||
case ILOpcode.Unaligned: return "unaligned.(alignment)";
|
||||
case ILOpcode.Unbox: return "unbox <typeTok>";
|
||||
case ILOpcode.UnboxAny: return "unbox.any <typeTok>";
|
||||
case ILOpcode.Volatile: return "volatile.";
|
||||
case ILOpcode.Xor: return "xor";
|
||||
}
|
||||
return "<OPCODE:" + ((short)opcode).ToString("X").PadLeft(2, '0') + ">";
|
||||
}
|
||||
|
||||
public string GetVariableName(MethodInfo mi, LocalVariableInfo localVariableInfo)
|
||||
{
|
||||
// TODO: read the PDB file (if exists) to get the local variable info
|
||||
return "local_" + localVariableInfo.LocalIndex.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ namespace UniversalEditor.Plugins.Executable.UserInterface.Editors.Executable.Co
|
||||
/// <summary>
|
||||
/// Provides a <see cref="CodeProvider" /> that translates MSIL code into C#.
|
||||
/// </summary>
|
||||
public class CSharpCodeProvider : CodeProvider
|
||||
public class CSharpCodeProvider : ILCodeProvider
|
||||
{
|
||||
public override string Title => "C#";
|
||||
public override string CodeFileExtension => ".cs";
|
||||
@ -191,84 +191,6 @@ namespace UniversalEditor.Plugins.Executable.UserInterface.Editors.Executable.Co
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private int? OpcodeToLiteralInt(ILOpcode opcode)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case ILOpcode.LdCI4_0:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
case ILOpcode.LdCI4_1:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case ILOpcode.LdCI4_2:
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
case ILOpcode.LdCI4_3:
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
case ILOpcode.LdCI4_4:
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
case ILOpcode.LdCI4_5:
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
case ILOpcode.LdCI4_6:
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
case ILOpcode.LdCI4_7:
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
case ILOpcode.LdCI4_8:
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
case ILOpcode.LdCI4_M1:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ILOpcode PeekOpcode(Reader r)
|
||||
{
|
||||
int sz = 0;
|
||||
ILOpcode opcode = ReadOpcode(r, out sz);
|
||||
if (sz == 0)
|
||||
return opcode;
|
||||
|
||||
r.Seek(-sz, SeekOrigin.Current);
|
||||
return opcode;
|
||||
}
|
||||
private ILOpcode ReadOpcode(Reader r, out int size)
|
||||
{
|
||||
if (r.EndOfStream)
|
||||
{
|
||||
size = 0;
|
||||
return ILOpcode.Nop;
|
||||
}
|
||||
|
||||
byte bytecode_b = r.ReadByte();
|
||||
short bytecode_s = bytecode_b;
|
||||
size = 1;
|
||||
|
||||
if (bytecode_s == 0xFE)
|
||||
{
|
||||
bytecode_s = BitConverter.ToInt16(new byte[] { bytecode_b, r.ReadByte() }, 0);
|
||||
size = 2;
|
||||
}
|
||||
return (ILOpcode)bytecode_s;
|
||||
}
|
||||
|
||||
protected override string GetSourceCodeInternal(FieldInfo fi, int indentLevel)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
@ -0,0 +1,394 @@
|
||||
//
|
||||
// ILCodeProvider.cs
|
||||
//
|
||||
// Author:
|
||||
// Michael Becker <alcexhim@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2021 Mike Becker's Software
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UniversalEditor.IO;
|
||||
|
||||
namespace UniversalEditor.Plugins.Executable.UserInterface.Editors.Executable.CodeProviders
|
||||
{
|
||||
public abstract class ILCodeProvider : CodeProvider
|
||||
{
|
||||
protected int? OpcodeToLiteralInt(ILOpcode opcode)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case ILOpcode.LdCI4_0:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
case ILOpcode.LdCI4_1:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case ILOpcode.LdCI4_2:
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
case ILOpcode.LdCI4_3:
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
case ILOpcode.LdCI4_4:
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
case ILOpcode.LdCI4_5:
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
case ILOpcode.LdCI4_6:
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
case ILOpcode.LdCI4_7:
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
case ILOpcode.LdCI4_8:
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
case ILOpcode.LdCI4_M1:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ILOpcode PeekOpcode(Reader r)
|
||||
{
|
||||
int sz = 0;
|
||||
ILOpcode opcode = ReadOpcode(r, out sz);
|
||||
if (sz == 0)
|
||||
return opcode;
|
||||
|
||||
r.Seek(-sz, SeekOrigin.Current);
|
||||
return opcode;
|
||||
}
|
||||
protected ILOpcode ReadOpcode(Reader r, out int size)
|
||||
{
|
||||
if (r.EndOfStream)
|
||||
{
|
||||
size = 0;
|
||||
return ILOpcode.Nop;
|
||||
}
|
||||
|
||||
byte bytecode_b = r.ReadByte();
|
||||
short bytecode_s = bytecode_b;
|
||||
size = 1;
|
||||
|
||||
if (bytecode_s == 0xFE)
|
||||
{
|
||||
bytecode_s = BitConverter.ToInt16(new byte[] { bytecode_b, r.ReadByte() }, 0);
|
||||
size = 2;
|
||||
}
|
||||
return (ILOpcode)bytecode_s;
|
||||
}
|
||||
|
||||
|
||||
private static BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
|
||||
|
||||
public MethodInfo[] GetMethods(Type type)
|
||||
{
|
||||
MethodInfo[] meths = type.GetMethods(bindingFlags);
|
||||
List<MethodInfo> list = new List<MethodInfo>();
|
||||
for (int j = 0; j < meths.Length; j++)
|
||||
{
|
||||
if (meths[j].IsSpecialName && (meths[j].Name.StartsWith("set_", StringComparison.OrdinalIgnoreCase) || meths[j].Name.StartsWith("get_", StringComparison.OrdinalIgnoreCase)) && (type.GetProperty(meths[j].Name.Substring(4), bindingFlags) != null))
|
||||
{
|
||||
// we can be REASONABLY sure that this is a property setter / getter,
|
||||
// and as we've already gotten all the properties, ignore it
|
||||
continue;
|
||||
}
|
||||
list.Add(meths[j]);
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
public FieldInfo[] GetFields(Type type, out List<string> AutoPropertyNames)
|
||||
{
|
||||
List<FieldInfo> list = new List<FieldInfo>();
|
||||
AutoPropertyNames = new List<string>();
|
||||
|
||||
FieldInfo[] fields = type.GetFields(bindingFlags);
|
||||
for (int j = 0; j < fields.Length; j++)
|
||||
{
|
||||
if (fields[j].Name.StartsWith("<", StringComparison.OrdinalIgnoreCase) && fields[j].Name.Contains(">"))
|
||||
{
|
||||
// might be a backing field
|
||||
int k__backingfield_name_start = fields[j].Name.IndexOf('<');
|
||||
int k__backingfield_name_end = fields[j].Name.IndexOf('>', k__backingfield_name_start);
|
||||
|
||||
string k__backingfield_name = fields[j].Name.Substring(k__backingfield_name_start + 1, k__backingfield_name_end - k__backingfield_name_start - 1);
|
||||
PropertyInfo pi = type.GetProperty(k__backingfield_name, bindingFlags);
|
||||
if (pi != null)
|
||||
{
|
||||
AutoPropertyNames.Add(pi.Name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(fields[j]);
|
||||
}
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
public string GetILOpcodeStr(short opcode)
|
||||
{
|
||||
return GetILOpcodeStr((ILOpcode)opcode);
|
||||
}
|
||||
public string GetILOpcodeStr(ILOpcode opcode)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case ILOpcode.Add: return "add";
|
||||
case ILOpcode.AddOvf: return "add.ovf";
|
||||
case ILOpcode.AddOvfUn: return "add.ovf.un";
|
||||
case ILOpcode.And: return "and";
|
||||
case ILOpcode.ArgList: return "arglist";
|
||||
case ILOpcode.Beq: return "beq <int32 (target)>";
|
||||
case ILOpcode.BeqS: return "beq <int32 (target)>";
|
||||
case ILOpcode.Bge: return "bge <int32 (target)>";
|
||||
case ILOpcode.BgeS: return "bge.s <int8 (target)>";
|
||||
case ILOpcode.BgeUn: return "bge.un <int32 (target)>";
|
||||
case ILOpcode.BgeUnS: return "bge.un.s <int8 (target)>";
|
||||
case ILOpcode.Bgt: return "bgt <int32 (target)>";
|
||||
case ILOpcode.BgtS: return "bgt.s <int8 (target)>";
|
||||
case ILOpcode.BgtUn: return "bgt.un <int32 (target)>";
|
||||
case ILOpcode.BgtUnS: return "bgt.un.s <int8 (target)>";
|
||||
case ILOpcode.Ble: return "ble <int32 (target)>";
|
||||
case ILOpcode.BleS: return "ble.s <int8 (target)>";
|
||||
case ILOpcode.BleUn: return "ble.un <int32 (target)>";
|
||||
case ILOpcode.BleUnS: return "ble.un.s <int8 (target)>";
|
||||
case ILOpcode.Blt: return "blt <int32 (target)>";
|
||||
case ILOpcode.BltS: return "blt.s <int8 (target)>";
|
||||
case ILOpcode.BltUn: return "blt.un <int32 (target)>";
|
||||
case ILOpcode.BltUnS: return "blt.un.s <int8 (target)>";
|
||||
case ILOpcode.BneUn: return "bne.un <int32 (target)>";
|
||||
case ILOpcode.BneUnS: return "bne.un.s <int8 (target)>";
|
||||
case ILOpcode.Box: return "box <typeTok>";
|
||||
case ILOpcode.Br: return "br <int32 (target)>";
|
||||
case ILOpcode.BrS: return "br.s <int8 (target)>";
|
||||
case ILOpcode.Break: return "break";
|
||||
case ILOpcode.BrFalse: return "brfalse <int32 (target)>";
|
||||
case ILOpcode.BrFalseS: return "brfalse.s <int8 (target)>";
|
||||
case ILOpcode.BrTrue: return "brtrue <int32 (target)>";
|
||||
case ILOpcode.BrTrueS: return "brtrue.s <int8 (target)>";
|
||||
case ILOpcode.Call: return "call <method>";
|
||||
case ILOpcode.CallI: return "calli <callsitedescr>";
|
||||
case ILOpcode.CallVirt: return "callvirt <method>";
|
||||
case ILOpcode.CastClass: return "castclass <class>";
|
||||
case ILOpcode.Ceq: return "ceq";
|
||||
case ILOpcode.Cgt: return "cgt";
|
||||
case ILOpcode.CgtUn: return "cgt.un";
|
||||
case ILOpcode.CkFinite: return "ckfinite";
|
||||
case ILOpcode.Clt: return "clt";
|
||||
case ILOpcode.CltUn: return "clt.un";
|
||||
case ILOpcode.Constrained: return "constrained <thisType>";
|
||||
case ILOpcode.ConvI: return "conv.i";
|
||||
case ILOpcode.ConvI1: return "conv.i1";
|
||||
case ILOpcode.ConvI2: return "conv.i2";
|
||||
case ILOpcode.ConvI4: return "conv.i4";
|
||||
case ILOpcode.ConvI8: return "conv.i8";
|
||||
case ILOpcode.ConvOvfI: return "conv.ovf.i";
|
||||
case ILOpcode.ConvOvfIUn: return "conv.ovf.i.un";
|
||||
case ILOpcode.ConvOvfI1: return "conv.ovf.i1";
|
||||
case ILOpcode.ConvOvfI1Un: return "conv.ovf.i1.un";
|
||||
case ILOpcode.ConvOvfI2: return "conv.ovf.i2";
|
||||
case ILOpcode.ConvOvfI2Un: return "conv.ovf.i2.un";
|
||||
case ILOpcode.ConvOvfI4: return "conv.ovf.i4";
|
||||
case ILOpcode.ConvOvfI4Un: return "conv.ovf.i4.un";
|
||||
case ILOpcode.ConvOvfI8: return "conv.ovf.i8";
|
||||
case ILOpcode.ConvOvfI8Un: return "conv.ovf.i8.un";
|
||||
case ILOpcode.ConvOvfU: return "conv.ovf.u";
|
||||
case ILOpcode.ConvOvfUUn: return "conv.ovf.u.un";
|
||||
case ILOpcode.ConvOvfU1: return "conv.ovf.u1";
|
||||
case ILOpcode.ConvOvfU1Un: return "conv.ovf.u1.un";
|
||||
case ILOpcode.ConvOvfU2: return "conv.ovf.u2";
|
||||
case ILOpcode.ConvOvfU2Un: return "conv.ovf.u2.un";
|
||||
case ILOpcode.ConvOvfU4: return "conv.ovf.u4";
|
||||
case ILOpcode.ConvOvfU4Un: return "conv.ovf.u4.un";
|
||||
case ILOpcode.ConvOvfU8: return "conv.ovf.u8";
|
||||
case ILOpcode.ConvOvfU8Un: return "conv.ovf.u8.un";
|
||||
case ILOpcode.ConvRUn: return "conv.r.un";
|
||||
case ILOpcode.ConvR4: return "conv.r4";
|
||||
case ILOpcode.ConvR8: return "conv.r8";
|
||||
case ILOpcode.ConvU: return "conv.u";
|
||||
case ILOpcode.ConvU1: return "conv.u1";
|
||||
case ILOpcode.ConvU2: return "conv.u2";
|
||||
case ILOpcode.ConvU4: return "conv.u4";
|
||||
case ILOpcode.ConvU8: return "conv.u8";
|
||||
case ILOpcode.CpBlk: return "cpblk";
|
||||
case ILOpcode.CpObj: return "cpobj <typeTok>";
|
||||
case ILOpcode.Div: return "div";
|
||||
case ILOpcode.DivUn: return "div.un";
|
||||
case ILOpcode.Dup: return "dup";
|
||||
case ILOpcode.EndFault: return "endfault";
|
||||
case ILOpcode.EndFilter: return "endfilter";
|
||||
// case ILOpcode.EndFinally: return "endfinally"; // same as endfault?
|
||||
case ILOpcode.InitBlk: return "initblk";
|
||||
case ILOpcode.InitObj: return "initobj <typeTok>";
|
||||
case ILOpcode.IsInst: return "isinst <class>";
|
||||
case ILOpcode.Jmp: return "jmp";
|
||||
case ILOpcode.LdArg: return "ldarg <uint16 (num)>";
|
||||
case ILOpcode.LdArg0: return "ldarg.0";
|
||||
case ILOpcode.LdArg1: return "ldarg.1";
|
||||
case ILOpcode.LdArg2: return "ldarg.2";
|
||||
case ILOpcode.LdArg3: return "ldarg.3";
|
||||
case ILOpcode.LdArgS: return "ldarg.s <uint8 (num)>";
|
||||
case ILOpcode.LdArgA: return "ldarg.a <uint16 (num)>";
|
||||
case ILOpcode.LdArgAS: return "ldarg.a.s <uint8 (num)>";
|
||||
case ILOpcode.LdCI4: return "ldc.i4 <int32 (num)>";
|
||||
case ILOpcode.LdCI4_M1: return "ldc.i4.m1";
|
||||
case ILOpcode.LdCI4_0: return "ldc.i4.0";
|
||||
case ILOpcode.LdCI4_1: return "ldc.i4.1";
|
||||
case ILOpcode.LdCI4_2: return "ldc.i4.2";
|
||||
case ILOpcode.LdCI4_3: return "ldc.i4.3";
|
||||
case ILOpcode.LdCI4_4: return "ldc.i4.4";
|
||||
case ILOpcode.LdCI4_5: return "ldc.i4.5";
|
||||
case ILOpcode.LdCI4_6: return "ldc.i4.6";
|
||||
case ILOpcode.LdCI4_7: return "ldc.i4.7";
|
||||
case ILOpcode.LdCI4_8: return "ldc.i4.8";
|
||||
case ILOpcode.LdCI4S: return "ldc.i4.s <int8 (num)>";
|
||||
case ILOpcode.LdCI8: return "ldc.i8 <int64 (num)>";
|
||||
case ILOpcode.LdCR4: return "ldc.r4 <float32 (num)>";
|
||||
case ILOpcode.LdCR8: return "ldc.r8 <float64 (num)>";
|
||||
case ILOpcode.LdElem: return "ldelem <typeTok>";
|
||||
case ILOpcode.LdElemI: return "ldelem.i";
|
||||
case ILOpcode.LdElemI1: return "ldelem.i1";
|
||||
case ILOpcode.LdElemU1: return "ldelem.u1";
|
||||
case ILOpcode.LdElemI2: return "ldelem.i2";
|
||||
case ILOpcode.LdElemU2: return "ldelem.u2";
|
||||
case ILOpcode.LdElemI4: return "ldelem.i4";
|
||||
case ILOpcode.LdElemU4: return "ldelem.u4";
|
||||
case ILOpcode.LdElemI8: return "ldelem.i8";
|
||||
case ILOpcode.LdElemR4: return "ldelem.r4";
|
||||
case ILOpcode.LdElemR8: return "ldelem.r8";
|
||||
case ILOpcode.LdElemRef: return "ldelem.ref";
|
||||
case ILOpcode.LdElemA: return "ldelema <class>";
|
||||
case ILOpcode.LdFld: return "ldfld <field>";
|
||||
case ILOpcode.LdFldA: return "ldflda <field>";
|
||||
case ILOpcode.LdFtn: return "ldftn <method>";
|
||||
case ILOpcode.LdIndI: return "ldind.i";
|
||||
case ILOpcode.LdIndI1: return "ldind.i1";
|
||||
case ILOpcode.LdIndU1: return "ldind.u1";
|
||||
case ILOpcode.LdIndI2: return "ldind.i2";
|
||||
case ILOpcode.LdIndU2: return "ldind.u2";
|
||||
case ILOpcode.LdIndI4: return "ldind.i4";
|
||||
case ILOpcode.LdIndU4: return "ldind.u4";
|
||||
case ILOpcode.LdIndI8: return "ldind.i8";
|
||||
case ILOpcode.LdIndR4: return "ldind.r4";
|
||||
case ILOpcode.LdIndR8: return "ldind.r8";
|
||||
case ILOpcode.LdLen: return "ldlen";
|
||||
case ILOpcode.LdLoc: return "ldloc <uint16 (indx)>";
|
||||
case ILOpcode.LdLoc0: return "ldloc.0";
|
||||
case ILOpcode.LdLoc1: return "ldloc.1";
|
||||
case ILOpcode.LdLoc2: return "ldloc.2";
|
||||
case ILOpcode.LdLoc3: return "ldloc.3";
|
||||
case ILOpcode.LdLocS: return "ldloc.s <uint8 (indx)>";
|
||||
case ILOpcode.LdLocA: return "ldloca <uint16 (indx)>";
|
||||
case ILOpcode.LdLocAS: return "ldloca.s <uint8 (indx)>";
|
||||
case ILOpcode.LdNull: return "ldnull";
|
||||
case ILOpcode.LdObj: return "ldobj <typeTok>";
|
||||
case ILOpcode.LdSFld: return "ldsfld <field>";
|
||||
case ILOpcode.LdSFldA: return "ldsflda <field>";
|
||||
case ILOpcode.LdStr: return "ldstr <string>";
|
||||
case ILOpcode.LdToken: return "ldtoken <token>";
|
||||
case ILOpcode.LdVirtFtn: return "ldvirtftn <method>";
|
||||
case ILOpcode.Leave: return "leave <int32 (target)>";
|
||||
case ILOpcode.LeaveS: return "leave <int8 (target)>";
|
||||
case ILOpcode.LocAlloc: return "localloc";
|
||||
case ILOpcode.MkRefAny: return "mkrefany <class>";
|
||||
case ILOpcode.Mul: return "mul";
|
||||
case ILOpcode.MulOvf: return "mul.ovf";
|
||||
case ILOpcode.MulOvfUn: return "mul.ovf.un";
|
||||
case ILOpcode.Neg: return "neg";
|
||||
case ILOpcode.NewArr: return "newarr <etype>";
|
||||
case ILOpcode.NewObj: return "newobj <ctor>";
|
||||
case ILOpcode.No: return "no.{typecheck, rangecheck, nullcheck}";
|
||||
case ILOpcode.Nop: return "nop";
|
||||
case ILOpcode.Not: return "not";
|
||||
case ILOpcode.Or: return "or";
|
||||
case ILOpcode.Pop: return "pop";
|
||||
case ILOpcode.Readonly: return "readonly.";
|
||||
case ILOpcode.RefAnyType: return "refanytype";
|
||||
case ILOpcode.RefAnyVal: return "refanyval <type>";
|
||||
case ILOpcode.Rem: return "rem";
|
||||
case ILOpcode.RemUn: return "rem.un";
|
||||
case ILOpcode.Ret: return "ret";
|
||||
case ILOpcode.Rethrow: return "rethrow";
|
||||
case ILOpcode.Shl: return "shl";
|
||||
case ILOpcode.Shr: return "shl";
|
||||
case ILOpcode.ShrUn: return "shl";
|
||||
case ILOpcode.SizeOf: return "sizeof <typeTok>";
|
||||
case ILOpcode.StArg: return "starg <uint16 (num)>";
|
||||
case ILOpcode.StArgS: return "starg.s <uint8 (num)>";
|
||||
case ILOpcode.StElem: return "stelem <typeTok>";
|
||||
case ILOpcode.StElemI: return "stelem.i";
|
||||
case ILOpcode.StElemI1: return "stelem.i1";
|
||||
case ILOpcode.StElemI2: return "stelem.i2";
|
||||
case ILOpcode.StElemI4: return "stelem.i4";
|
||||
case ILOpcode.StElemI8: return "stelem.i8";
|
||||
case ILOpcode.StElemR4: return "stelem.r4";
|
||||
case ILOpcode.StElemR8: return "stelem.r8";
|
||||
case ILOpcode.StElemRef: return "stelem.ref";
|
||||
case ILOpcode.StFld: return "stfld <field>";
|
||||
case ILOpcode.StIndI: return "stind.i";
|
||||
case ILOpcode.StIndI1: return "stind.i1";
|
||||
case ILOpcode.StIndI2: return "stind.i2";
|
||||
case ILOpcode.StIndI4: return "stind.i4";
|
||||
case ILOpcode.StIndI8: return "stind.i8";
|
||||
case ILOpcode.StIndR4: return "stind.r4";
|
||||
case ILOpcode.StIndR8: return "stind.r8";
|
||||
case ILOpcode.StIndRef: return "stind.ref";
|
||||
case ILOpcode.StLoc: return "stloc <uint16 (indx)>";
|
||||
case ILOpcode.StLoc0: return "stloc.0";
|
||||
case ILOpcode.StLoc1: return "stloc.1";
|
||||
case ILOpcode.StLoc2: return "stloc.2";
|
||||
case ILOpcode.StLoc3: return "stloc.3";
|
||||
case ILOpcode.StLocS: return "stloc.s <uint8 (indx)>";
|
||||
case ILOpcode.StObj: return "stobj <typeTok>";
|
||||
case ILOpcode.StSFld: return "stsfld <field>";
|
||||
case ILOpcode.Sub: return "sub";
|
||||
case ILOpcode.SubOvf: return "sub.ovf";
|
||||
case ILOpcode.SubOvfUn: return "sub.ovf.un";
|
||||
case ILOpcode.Switch: return "switch <uint32, int32, int32 (t1..tN)>";
|
||||
case ILOpcode.Tail: return "tail.";
|
||||
case ILOpcode.Throw: return "throw";
|
||||
case ILOpcode.Unaligned: return "unaligned.(alignment)";
|
||||
case ILOpcode.Unbox: return "unbox <typeTok>";
|
||||
case ILOpcode.UnboxAny: return "unbox.any <typeTok>";
|
||||
case ILOpcode.Volatile: return "volatile.";
|
||||
case ILOpcode.Xor: return "xor";
|
||||
}
|
||||
return "<OPCODE:" + ((short)opcode).ToString("X").PadLeft(2, '0') + ">";
|
||||
}
|
||||
|
||||
public string GetVariableName(MethodInfo mi, LocalVariableInfo localVariableInfo)
|
||||
{
|
||||
// TODO: read the PDB file (if exists) to get the local variable info
|
||||
return "local_" + localVariableInfo.LocalIndex.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,13 +22,15 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UniversalEditor.Accessors;
|
||||
using UniversalEditor.IO;
|
||||
|
||||
namespace UniversalEditor.Plugins.Executable.UserInterface.Editors.Executable.CodeProviders
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a <see cref="CodeProvider" /> that translates MSIL code into VB.NET.
|
||||
/// </summary>
|
||||
public class VisualBasicCodeProvider : CodeProvider
|
||||
public class VisualBasicCodeProvider : ILCodeProvider
|
||||
{
|
||||
public override string Title => "VB.NET";
|
||||
public override string CodeFileExtension => ".vb";
|
||||
@ -185,7 +187,62 @@ namespace UniversalEditor.Plugins.Executable.UserInterface.Editors.Executable.Co
|
||||
}
|
||||
protected override string GetSourceCodeInternal(MethodInfo mi, int indentLevel)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
string indentStr = new string('\t', indentLevel);
|
||||
sb.Append(indentStr);
|
||||
sb.Append(GetMethodSignature(mi));
|
||||
|
||||
MethodBody mb = mi.GetMethodBody();
|
||||
if (mb != null)
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.Append(GetBeginBlock(mi, indentLevel));
|
||||
sb.AppendLine();
|
||||
|
||||
for (int i = 0; i < mb.LocalVariables.Count; i++)
|
||||
{
|
||||
sb.Append(new string('\t', indentLevel + 1));
|
||||
sb.Append("Dim ");
|
||||
sb.Append(GetVariableName(mi, mb.LocalVariables[i]));
|
||||
sb.Append(" As ");
|
||||
sb.Append(GetTypeName(mb.LocalVariables[i].LocalType));
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
if (mb.LocalVariables.Count > 0)
|
||||
sb.AppendLine();
|
||||
|
||||
byte[] bytecode = mb.GetILAsByteArray();
|
||||
MemoryAccessor ma = new MemoryAccessor(bytecode);
|
||||
Reader r = new Reader(ma);
|
||||
while (!r.EndOfStream)
|
||||
{
|
||||
int sz = 0;
|
||||
ILOpcode opcode = ReadOpcode(r, out sz);
|
||||
ILOpcode opcode2 = PeekOpcode(r);
|
||||
|
||||
sb.Append(new string('\t', indentLevel + 1));
|
||||
|
||||
|
||||
if (opcode2 == ILOpcode.NewArr)
|
||||
{
|
||||
int? lit = OpcodeToLiteralInt(opcode);
|
||||
sb.Append(String.Format("Dim X As **TYPE**() = New X({0})", lit.GetValueOrDefault(0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(GetILOpcodeStr(opcode));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(GetEndBlock(mi, indentLevel));
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(';');
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
protected override string GetMethodSignatureInternal(MethodInfo mi)
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
<Compile Include="Editors\Executable\ILOpcode.cs" />
|
||||
<Compile Include="Editors\Executable\NonLayout\ExecutableEditor.cs" />
|
||||
<Compile Include="Editors\Executable\NonLayout\ManagedAssemblyPanel.cs" />
|
||||
<Compile Include="Editors\Executable\CodeProviders\ILCodeProvider.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Editors\" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user