Просмотр исходного кода

Unity3d使用LSharp热更新逻辑代码例子

tanghai 11 лет назад
Родитель
Сommit
44566e81d1
100 измененных файлов с 13547 добавлено и 0 удалено
  1. 1 0
      .gitignore
  2. 5 0
      Unity/Assets/Plugins.meta
  3. 5 0
      Unity/Assets/Plugins/CLRSharp.meta
  4. 262 0
      Unity/Assets/Plugins/CLRSharp/CLRSharp_Env.cs
  5. 8 0
      Unity/Assets/Plugins/CLRSharp/CLRSharp_Env.cs.meta
  6. 5 0
      Unity/Assets/Plugins/CLRSharp/CrossBind.meta
  7. 106 0
      Unity/Assets/Plugins/CLRSharp/CrossBind/Yield.cs
  8. 8 0
      Unity/Assets/Plugins/CLRSharp/CrossBind/Yield.cs.meta
  9. 5 0
      Unity/Assets/Plugins/CLRSharp/Execute.meta
  10. 42 0
      Unity/Assets/Plugins/CLRSharp/Execute/CodeBody.cs
  11. 8 0
      Unity/Assets/Plugins/CLRSharp/Execute/CodeBody.cs.meta
  12. 1195 0
      Unity/Assets/Plugins/CLRSharp/Execute/Context.cs
  13. 8 0
      Unity/Assets/Plugins/CLRSharp/Execute/Context.cs.meta
  14. 2273 0
      Unity/Assets/Plugins/CLRSharp/Execute/StackFrame.cs
  15. 8 0
      Unity/Assets/Plugins/CLRSharp/Execute/StackFrame.cs.meta
  16. 1509 0
      Unity/Assets/Plugins/CLRSharp/Execute/ValueOnStack.cs
  17. 8 0
      Unity/Assets/Plugins/CLRSharp/Execute/ValueOnStack.cs.meta
  18. 5 0
      Unity/Assets/Plugins/CLRSharp/Interface.meta
  19. 50 0
      Unity/Assets/Plugins/CLRSharp/Interface/EnvAndLog.cs
  20. 8 0
      Unity/Assets/Plugins/CLRSharp/Interface/EnvAndLog.cs.meta
  21. 5 0
      Unity/Assets/Plugins/CLRSharp/Type.meta
  22. 5 0
      Unity/Assets/Plugins/CLRSharp/Type/CLRSharp.meta
  23. 39 0
      Unity/Assets/Plugins/CLRSharp/Type/CLRSharp/CLRSharp_Instance.cs
  24. 8 0
      Unity/Assets/Plugins/CLRSharp/Type/CLRSharp/CLRSharp_Instance.cs.meta
  25. 439 0
      Unity/Assets/Plugins/CLRSharp/Type/CLRSharp/CLRSharp_Type.cs
  26. 8 0
      Unity/Assets/Plugins/CLRSharp/Type/CLRSharp/CLRSharp_Type.cs.meta
  27. 5 0
      Unity/Assets/Plugins/CLRSharp/Type/Delegate.meta
  28. 224 0
      Unity/Assets/Plugins/CLRSharp/Type/Delegate/Delegate_Helper.cs
  29. 8 0
      Unity/Assets/Plugins/CLRSharp/Type/Delegate/Delegate_Helper.cs.meta
  30. 5 0
      Unity/Assets/Plugins/CLRSharp/Type/System.meta
  31. 336 0
      Unity/Assets/Plugins/CLRSharp/Type/System/System_Type.cs
  32. 8 0
      Unity/Assets/Plugins/CLRSharp/Type/System/System_Type.cs.meta
  33. 145 0
      Unity/Assets/Plugins/CLRSharp/Type/Type_Common.cs
  34. 8 0
      Unity/Assets/Plugins/CLRSharp/Type/Type_Common.cs.meta
  35. 171 0
      Unity/Assets/Plugins/CLRSharp/Type/Type_List.cs
  36. 8 0
      Unity/Assets/Plugins/CLRSharp/Type/Type_List.cs.meta
  37. 5 0
      Unity/Assets/Plugins/Libs.meta
  38. BIN
      Unity/Assets/Plugins/Libs/Mono.Cecil.Mdb.dll
  39. 7 0
      Unity/Assets/Plugins/Libs/Mono.Cecil.Mdb.dll.meta
  40. BIN
      Unity/Assets/Plugins/Libs/Mono.Cecil.dll
  41. 7 0
      Unity/Assets/Plugins/Libs/Mono.Cecil.dll.meta
  42. 5 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb.meta
  43. 5 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb.meta
  44. 249 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitAccess.cs
  45. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitAccess.cs.meta
  46. 74 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitSet.cs
  47. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitSet.cs.meta
  48. 2435 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/CvInfo.cs
  49. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/CvInfo.cs.meta
  50. 111 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DataStream.cs
  51. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DataStream.cs.meta
  52. 41 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs
  53. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs.meta
  54. 59 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiHeader.cs
  55. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiHeader.cs.meta
  56. 57 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs
  57. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs.meta
  58. 42 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiSecCon.cs
  59. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiSecCon.cs.meta
  60. 583 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/IntHashTable.cs
  61. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/IntHashTable.cs.meta
  62. 77 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/Interfaces.cs
  63. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/Interfaces.cs.meta
  64. 58 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/MsfDirectory.cs
  65. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/MsfDirectory.cs.meta
  66. 89 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbConstant.cs
  67. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbConstant.cs.meta
  68. 20 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbDebugException.cs
  69. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbDebugException.cs.meta
  70. 20 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbException.cs
  71. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbException.cs.meta
  72. 439 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFile.cs
  73. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFile.cs.meta
  74. 90 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs
  75. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs.meta
  76. 452 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFunction.cs
  77. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFunction.cs.meta
  78. 29 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLine.cs
  79. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLine.cs.meta
  80. 23 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLines.cs
  81. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLines.cs.meta
  82. 40 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbReader.cs
  83. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbReader.cs.meta
  84. 122 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbScope.cs
  85. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbScope.cs.meta
  86. 40 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSlot.cs
  87. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSlot.cs.meta
  88. 29 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSource.cs
  89. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSource.cs.meta
  90. 33 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs
  91. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs.meta
  92. 5 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb.meta
  93. 41 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs
  94. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs.meta
  95. 103 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs
  96. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs.meta
  97. 796 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ModuleMetadata.cs
  98. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ModuleMetadata.cs.meta
  99. 196 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbHelper.cs
  100. 8 0
      Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbHelper.cs.meta

+ 1 - 0
.gitignore

@@ -26,3 +26,4 @@ _ReSharper.CSharp/
 *.opensdf
 *.sdf
 /CSharp/CSharp.sln.ide
+/Unity/Library

+ 5 - 0
Unity/Assets/Plugins.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: 064fc127e21b5c24da06dd305a52cf4a
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/CLRSharp.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: 16029f96e8f84644bac80f48e815cc31
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 262 - 0
Unity/Assets/Plugins/CLRSharp/CLRSharp_Env.cs

@@ -0,0 +1,262 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    
+    public class CLRSharp_Environment : ICLRSharp_Environment
+    {
+        public string version
+        {
+            get
+            {
+                return "0.36.5Alpha";
+            }
+        }
+        public ICLRSharp_Logger logger
+        {
+            get;
+            private set;
+        }
+        public CLRSharp_Environment(ICLRSharp_Logger logger)
+        {
+            this.logger = logger;
+            logger.Log_Warning("CLR# Ver:" + version + " Inited.");
+
+            this.RegCrossBind(new CrossBind_IEnumerable());
+            this.RegCrossBind(new CrossBind_IEnumerator());
+        }
+        Dictionary<string, ICLRType> mapType = new Dictionary<string, ICLRType>();
+        //public Dictionary<string, Mono.Cecil.ModuleDefinition> mapModule = new Dictionary<string, Mono.Cecil.ModuleDefinition>();
+        public void LoadModule(System.IO.Stream dllStream)
+        {
+            LoadModule(dllStream, null, null);
+        }
+        public void LoadModule(System.IO.Stream dllStream, System.IO.Stream pdbStream, Mono.Cecil.Cil.ISymbolReaderProvider debugInfoLoader)
+        {
+            var module = Mono.Cecil.ModuleDefinition.ReadModule(dllStream);
+            if (debugInfoLoader != null && pdbStream != null)
+            {
+                module.ReadSymbols(debugInfoLoader.GetSymbolReader(module, pdbStream));
+            }
+            //mapModule[module.Name] = module;
+            if (module.HasTypes)
+            {
+                foreach (var t in module.Types)
+                {
+                    mapType[t.FullName] = new Type_Common_CLRSharp(this, t);
+                }
+            }
+            if (module.HasAssemblyReferences)
+            {
+                foreach (var ar in module.AssemblyReferences)
+                {
+                    if (moduleref.Contains(ar.Name) == false)
+                        moduleref.Add(ar.Name);
+                }
+            }
+        }
+        public List<System.Reflection.Assembly> assemblylist;
+        public void AddSerachAssembly(System.Reflection.Assembly assembly)
+        {
+            if (assemblylist == null)
+                assemblylist = new List<System.Reflection.Assembly>();
+            assemblylist.Add(assembly);
+        }
+        public void LoadModule_OnlyName(System.IO.Stream dllStream)
+        {
+            var module = Mono.Cecil.ModuleDefinition.ReadModule(dllStream);
+            if (moduleref.Contains(module.Name) == false)
+                moduleref.Add(module.Name);
+            if (module.HasAssemblyReferences)
+            {
+                foreach (var ar in module.AssemblyReferences)
+                {
+                    if (moduleref.Contains(ar.Name) == false)
+                        moduleref.Add(ar.Name);
+                }
+            }
+        }
+        public CodeBody CreateCodeBody(Method_Common_CLRSharp method)
+        {
+            return new CodeBody(this, method.method_CLRSharp);
+        }
+        List<string> moduleref = new List<string>();
+        public string[] GetAllTypes()
+        {
+            string[] array = new string[mapType.Count];
+            mapType.Keys.CopyTo(array, 0);
+            return array;
+        }
+        public string[] GetModuleRefNames()
+        {
+            return moduleref.ToArray();
+        }
+        //得到类型的时候应该得到模块内Type或者真实Type
+        //一个统一的Type,然后根据具体情况调用两边
+
+        public ICLRType GetType(string fullname)
+        {
+            ICLRType type = null;
+            bool b = mapType.TryGetValue(fullname, out type);
+            if (!b)
+            {
+                List<ICLRType> subTypes = new List<ICLRType>();
+                if (fullname.Contains("<>") || fullname.Contains("/"))//匿名类型
+                {
+                    string[] subts = fullname.Split('/');
+                    ICLRType ft = GetType(subts[0]);
+                    if (ft is ICLRType_Sharp)
+                    {
+                        for (int i = 1; i < subts.Length; i++)
+                        {
+                            ft = ft.GetNestType(this, subts[i]);
+                        }
+                        return ft;
+                    }
+                }
+                string fullnameT = fullname;//.Replace('/', '+');
+
+                if (fullnameT.Contains("<"))
+                {
+                    string outname = "";
+                    int depth = 0;
+                    int lastsplitpos = 0;
+                    for (int i = 0; i < fullname.Length; i++)
+                    {
+                        string checkname = null;
+                        if (fullname[i] == '/')
+                        {
+
+                        }
+                        else if (fullname[i] == '<')
+                        {
+                            if (i != 0)
+                                depth++;
+                            if (depth == 1)//
+                            {
+                                lastsplitpos = i;
+                                outname += "[";
+                                continue;
+                            }
+
+                        }
+                        else if (fullname[i] == '>')
+                        {
+                            if (depth == 1)
+                            {
+                                checkname = fullnameT.Substring(lastsplitpos + 1, i - lastsplitpos - 1);
+                                var subtype = GetType(checkname);
+                                subTypes.Add(subtype);
+                                if (subtype is ICLRType_Sharp) subtype = GetType(typeof(CLRSharp_Instance));
+                                outname += "[" + subtype.FullNameWithAssembly + "]";
+                                lastsplitpos = i;
+                            }
+                            //if(depth>0)
+                            depth--;
+                            if (depth == 0)
+                            {
+                                outname += "]";
+                                continue;
+                            }
+                            else if (depth < 0)
+                            {
+                                depth = 0;
+                            }
+                        }
+                        else if (fullname[i] == ',')
+                        {
+                            if (depth == 1)
+                            {
+                                checkname = fullnameT.Substring(lastsplitpos + 1, i - lastsplitpos - 1);
+                                var subtype = GetType(checkname);
+                                subTypes.Add(subtype);
+                                if (subtype is ICLRType_Sharp) subtype = GetType(typeof(CLRSharp_Instance));
+                                outname += "[" + subtype.FullNameWithAssembly + "],";
+                                lastsplitpos = i;
+                            }
+                        }
+                        if (depth == 0)
+                        {
+                            outname += fullnameT[i];
+                        }
+                    }
+                    fullnameT = outname;
+                    //    fullnameT = fullnameT.Replace('<', '[');
+                    //fullnameT = fullnameT.Replace('>', ']');
+
+
+                }
+                fullnameT = fullnameT.Replace('/', '+');
+                System.Type t = System.Type.GetType(fullnameT);
+
+                if (t == null)
+                {
+                    if (assemblylist != null)
+                    {
+                        foreach (var i in assemblylist)
+                        {
+                            t = i.GetType(fullnameT);
+                            if (t != null)
+                                break;
+                        }
+                    }
+                    if (t == null)
+                    {
+                        foreach (var rm in moduleref)
+                        {
+                            t = System.Type.GetType(fullnameT + "," + rm);
+                            if (t != null)
+                            {
+                                fullnameT = fullnameT + "," + rm;
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (t != null)
+                {
+                    type = new Type_Common_System(this, t, subTypes.ToArray());
+                }
+                mapType[fullname] = type;
+            }
+            return type;
+        }
+
+
+        public ICLRType GetType(System.Type systemType)
+        {
+            ICLRType type = null;
+            bool b = mapType.TryGetValue(systemType.FullName, out type);
+            if (!b)
+            {
+                type = new Type_Common_System(this, systemType,  null);
+                mapType[systemType.FullName] = type;
+            }
+            return type;
+        }
+        public void RegType(ICLRType type)
+        {
+            mapType[type.FullName] = type;
+        }
+
+        /// <summary>
+        /// 交叉绑定工具,让脚本继承程序类型用的
+        /// </summary>
+        Dictionary<Type, ICrossBind> crossBind = new Dictionary<Type, ICrossBind>();
+        public void RegCrossBind(ICrossBind bind)
+        {
+            crossBind[bind.Type] = bind;
+        }
+
+        public ICrossBind GetCrossBind(Type type)
+        {
+            ICrossBind bind = null;
+
+            crossBind.TryGetValue(type, out bind);
+            return bind;
+        }
+
+    }
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/CLRSharp_Env.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: fb600bfb3104e1441b86c333adb58227
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/CLRSharp/CrossBind.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: 02ec683e7227bf54abc8638cf3be69e5
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 106 - 0
Unity/Assets/Plugins/CLRSharp/CrossBind/Yield.cs

@@ -0,0 +1,106 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    public class CrossBind_IEnumerable : ICrossBind
+    {
+        public Type Type
+        {
+            get { return typeof(IEnumerable); }
+        }
+
+        public object CreateBind(CLRSharp_Instance inst)
+        {
+            return new Base_IEnumerable(inst);
+        }
+
+        class Base_IEnumerable : IEnumerable
+        {
+            CLRSharp_Instance inst;
+            public Base_IEnumerable(CLRSharp_Instance inst)
+            {
+                this.inst = inst;
+
+            }
+
+            public IEnumerator GetEnumerator()
+            {
+                var context = ThreadContext.activeContext;
+                var _type = context.environment.GetType(typeof(IEnumerable));
+                var _method = this.inst.type.GetMethod(_type.FullName+"."+"GetEnumerator", MethodParamList.constEmpty());
+                var obj = _method.Invoke(context, inst, null) as CLRSharp_Instance;
+
+                return context.environment.GetCrossBind(typeof(IEnumerator)).CreateBind(obj) as IEnumerator;
+            }
+        }
+    }
+    public class CrossBind_IEnumerator : ICrossBind
+    {
+        public Type Type
+        {
+            get { return typeof(IEnumerator); }
+        }
+
+        public object CreateBind(CLRSharp_Instance inst)
+        {
+            return new Base_IEnumerator(inst);
+        }
+
+        class Base_IEnumerator : IEnumerator
+        {
+            CLRSharp_Instance inst;
+            public Base_IEnumerator(CLRSharp_Instance inst)
+            { 
+                var context = ThreadContext.activeContext;
+                this.inst = inst;
+                var ms = this.inst.type.GetMethodNames();
+                foreach(string name in ms)
+                {
+                    if(name.Contains("MoveNext"))
+                        _MoveNext = this.inst.type.GetMethod(name, MethodParamList.constEmpty());
+                    if (name.Contains(".get_Current"))
+                        _get_Current = this.inst.type.GetMethod(name, MethodParamList.constEmpty());
+                    if (name.Contains(".Reset"))
+                        _Reset = this.inst.type.GetMethod(name, MethodParamList.constEmpty());
+                }
+            }
+            IMethod _MoveNext;
+            IMethod _get_Current;
+            IMethod _Reset;
+
+
+            public object Current
+            {
+                get
+                {
+                    var context = ThreadContext.activeContext;
+                    var obj = _get_Current.Invoke(context, inst, null);
+
+                    return obj;
+                }
+            }
+
+            public bool MoveNext()
+            {
+                var context = ThreadContext.activeContext;
+                var obj = _MoveNext.Invoke(context, inst, null) as VBox;
+
+                return obj.ToBool();
+            }
+
+            public void Reset()
+            {
+                var context = ThreadContext.activeContext;
+
+                var obj = _Reset.Invoke(context, inst, null);
+
+            }
+        }
+    }
+
+}
+
+

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/CrossBind/Yield.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 05580974f557ad243a9da9ead771061e
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/CLRSharp/Execute.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: aa53d6b785dcbf54592add81af72cde8
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 42 - 0
Unity/Assets/Plugins/CLRSharp/Execute/CodeBody.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    public class CodeBody
+    {
+        //以后准备用自定义Body采集一遍,可以先过滤处理掉Mono.Cecil的代码中的指向,执行会更快
+        public CodeBody(CLRSharp.ICLRSharp_Environment env, Mono.Cecil.MethodDefinition _def)
+        {
+            this.method = _def;
+            Init(env);
+        }
+        public MethodParamList typelistForLoc = null;
+        Mono.Cecil.MethodDefinition method;
+        public Mono.Cecil.Cil.MethodBody bodyNative
+        {
+            get
+            {
+                return method.Body;
+            }
+        }
+        bool bInited = false;
+        public void Init(CLRSharp.ICLRSharp_Environment env)
+        {
+            if (bInited) return;
+            if(bodyNative.HasVariables)
+            {
+                typelistForLoc = new MethodParamList(env, bodyNative.Variables);
+ 
+            }
+        }
+        /// <summary>
+        /// 预约的优化项目,暂不进行
+        /// </summary>
+        public void cacheBody()
+        {
+
+        }
+    }
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/Execute/CodeBody.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 056e3d478983cf240af39ae2bc551dea
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 1195 - 0
Unity/Assets/Plugins/CLRSharp/Execute/Context.cs

@@ -0,0 +1,1195 @@
+using Mono.Cecil.Cil;
+using System;
+using System.Collections.Generic;
+
+
+namespace CLRSharp
+{
+    /// <summary>
+    /// 线程上下文
+    /// 一个线程上下文表示一次调用,直到结束
+    /// </summary>
+    public class ThreadContext
+    {
+        [ThreadStatic]
+        static ThreadContext _activeContext = null;
+        public static ThreadContext activeContext
+        {
+            get
+            {
+                return _activeContext;
+            }
+        }
+        public ICLRSharp_Environment environment
+        {
+            get;
+            private set;
+        }
+        public int DebugLevel
+        {
+            get;
+            private set;
+        }
+        public ThreadContext(ICLRSharp_Environment env)
+        {
+            this.environment = env;
+            DebugLevel = 0;
+        }
+        public ThreadContext(ICLRSharp_Environment env, int DebugLevel)
+        {
+            this.environment = env;
+            this.DebugLevel = DebugLevel;
+        }
+        public Stack<StackFrame> GetStackFrames()
+        {
+            return stacks;
+        }
+        Stack<StackFrame> stacks = new Stack<StackFrame>();
+        public bool SetNoTry = false;
+        public string Dump()
+        {
+            string str = "";
+            foreach (StackFrame s in GetStackFrames())
+            {
+                var pos = s._pos;
+
+                Instruction sqIns = pos;
+                while (sqIns != null && sqIns.SequencePoint == null)
+                {
+                    sqIns = sqIns.Previous;
+                }
+                if (sqIns != null && sqIns.SequencePoint != null)
+                {
+                    str += sqIns.SequencePoint.Document.Url + "(" + sqIns.SequencePoint.StartLine + ")\n";
+                }
+                else
+                {
+                    str +="!no pdb info,no code filename(no line)!\n";
+                }
+                if (pos == null)
+                {
+                    continue;
+                }
+                str += "    IL " + pos.ToString() + "\n";
+                if (s._params != null)
+                {
+                    str += "    ===Params(" + s._params.Length + ")===\n";
+                    for (int i = 0; i < s._params.Length; i++)
+                    {
+                        str += "        param" + i.ToString("D04") + s._params[i] + "\n";
+                    }
+                }
+                str += "    ===VarSlots(" + s.slotVar.Count + ")===\n";
+                for (int i = 0; i < s.slotVar.Count; i++)
+                {
+                    str += "        var" + i.ToString("D04") + s.slotVar[i] + "\n";
+                }
+            }
+            return str;
+        }
+        public object ExecuteFunc(IMethod_Sharp method, object _this, object[] _params)
+        {
+            _activeContext = this;
+            if (this.DebugLevel >= 9)
+            {
+                environment.logger.Log("<Call>::" + method.DeclaringType.FullName + "::" + method.Name.ToString());
+
+            }
+            StackFrame stack = new StackFrame(method.Name, method.isStatic);
+            stacks.Push(stack);
+
+            object[] _withp = null;
+            bool isctor = method.Name == ".ctor";
+            if (isctor)
+            {
+                //CLRSharp_Instance pthis = new CLRSharp_Instance(GetType(func.ReturnType) as Type_Common_CLRSharp);
+                //StackFrame.RefObj pthis = new StackFrame.RefObj(stack, 0, StackFrame.RefType.arg);
+                _withp = new object[_params == null ? 1 : (_params.Length + 1)];
+                if (_params != null)
+                    _params.CopyTo(_withp, 1);
+                _withp[0] = _this;
+            }
+            else
+            {
+                if (!method.isStatic)
+                {
+                    _withp = new object[(_params == null) ? 1 : (_params.Length + 1)];
+                    _withp[0] = _this;
+                    if (_params != null)
+                        _params.CopyTo(_withp, 1);
+                }
+                else
+                {
+                    _withp = _params;
+                }
+            }
+            stack.SetParams(_withp);
+
+            if (method.body != null)
+            {
+                stack.Init(method.body);
+                stack._pos = method.body.bodyNative.Instructions[0];
+
+                if (method.body.bodyNative.HasExceptionHandlers && !SetNoTry)
+                {
+                    RunCodeWithTry(method.body, stack);
+                }
+                else
+                {
+                    RunCode(stack, method.body);
+                }
+            }
+
+            if (this.DebugLevel >= 9)
+            {
+                environment.logger.Log("<CallEnd>");
+
+            }
+            var ret = stacks.Pop().Return();
+
+            return isctor ? _this : ret;
+
+            //if (func.HasBody)
+            //{
+            //    RunCode(stack, func.Body.Instructions);
+            //}
+            //var ret = stacks.Pop().Return();
+            //if (this.DebugLevel >= 9)
+            //{
+            //    environment.logger.Log("<CallEnd>");
+
+            //}
+            //return ret;
+
+
+
+        }
+
+        private void RunCodeWithTry(CodeBody body, StackFrame stack)
+        {
+            try
+            {
+
+                RunCode(stack, body);
+
+            }
+            catch (Exception err)
+            {
+                bool bEH = false;
+                if (body.bodyNative.HasExceptionHandlers)
+                {
+                    bEH = JumpToErr(body, stack, err);
+                }
+                if (!bEH)
+                {
+                    throw err;
+                }
+            }
+        }
+        ICLRType GetType(string fullname)
+        {
+            var type = environment.GetType(fullname);
+            ICLRType_Sharp stype = type as ICLRType_Sharp;
+            if (stype != null && stype.NeedCCtor)
+            {
+                //执行.cctor
+                stype.InvokeCCtor(this);
+            }
+            return type;
+        }
+
+        ICLRType GetType(object token)
+        {
+            token.GetHashCode();
+            Mono.Cecil.ModuleDefinition module = null;
+            string typename = null;
+            if (token is Mono.Cecil.TypeDefinition)
+            {
+                Mono.Cecil.TypeDefinition _def = (token as Mono.Cecil.TypeDefinition);
+                module = _def.Module;
+                typename = _def.FullName;
+            }
+            else if (token is Mono.Cecil.TypeReference)
+            {
+                Mono.Cecil.TypeReference _ref = (token as Mono.Cecil.TypeReference);
+                module = _ref.Module;
+                typename = _ref.FullName;
+            }
+            else
+            {
+                throw new NotImplementedException();
+            }
+            return GetType(typename);
+        }
+        Dictionary<int, IMethod> methodCache = new Dictionary<int, IMethod>();
+        Dictionary<int, IField> fieldCache = new Dictionary<int, IField>();
+        IMethod GetMethod(object token)
+        {
+            IMethod __method = null;
+            if (methodCache.TryGetValue(token.GetHashCode(), out __method))
+            {
+                return __method;
+            }
+            Mono.Cecil.ModuleDefinition module = null;
+            string methodname = null;
+            string typename = null;
+            MethodParamList genlist = null;
+            MethodParamList list = null;
+            if (token is Mono.Cecil.MethodReference)
+            {
+                Mono.Cecil.MethodReference _ref = (token as Mono.Cecil.MethodReference);
+                module = _ref.Module;
+                methodname = _ref.Name;
+                typename = _ref.DeclaringType.FullName;
+                list = new MethodParamList(environment, _ref);
+                if (_ref.IsGenericInstance)
+                {
+                    Mono.Cecil.GenericInstanceMethod gmethod = _ref as Mono.Cecil.GenericInstanceMethod;
+                    genlist = new MethodParamList(environment, gmethod);
+
+                }
+            }
+            else if (token is Mono.Cecil.MethodDefinition)
+            {
+                Mono.Cecil.MethodDefinition _def = token as Mono.Cecil.MethodDefinition;
+                module = _def.Module;
+                methodname = _def.Name;
+                typename = _def.DeclaringType.FullName;
+                list = new MethodParamList(environment, _def);
+                if (_def.IsGenericInstance)
+                {
+                    throw new NotImplementedException();
+                    //Mono.Cecil.GenericInstanceMethod gmethod = _def as Mono.Cecil.GenericInstanceMethod;
+                    //genlist = new MethodParamList(environment, gmethod);
+                }
+            }
+            else
+            {
+                throw new NotImplementedException();
+            }
+            var typesys = GetType(typename);
+            if (typesys == null)
+                throw new Exception("type can't find:" + typename);
+
+
+            IMethod _method = null;
+            if (genlist != null)
+            {
+                _method = typesys.GetMethodT(methodname, genlist, list);
+            }
+            else
+            {
+                _method = typesys.GetMethod(methodname, list);
+            }
+            methodCache[token.GetHashCode()] = _method;
+            return _method;
+        }
+        IMethod GetNewForArray(object token)
+        {
+            IMethod __method = null;
+            if (methodCache.TryGetValue(token.GetHashCode(), out __method))
+            {
+                return __method;
+            }
+            Mono.Cecil.ModuleDefinition module = null;
+            string typename = null;
+            if (token is Mono.Cecil.TypeDefinition)
+            {
+                Mono.Cecil.TypeDefinition _def = (token as Mono.Cecil.TypeDefinition);
+                module = _def.Module;
+                typename = _def.FullName;
+            }
+            else if (token is Mono.Cecil.TypeReference)
+            {
+                Mono.Cecil.TypeReference _ref = (token as Mono.Cecil.TypeReference);
+                module = _ref.Module;
+                typename = _ref.FullName;
+            }
+            else
+            {
+                throw new NotImplementedException();
+            }
+
+            ICLRType _Itype = GetType(typename);
+            typename += "[]";
+            //var _type = context.environment.GetType(typename, type.Module);
+            var _type = GetType(typename);
+
+            MethodParamList tlist = MethodParamList.const_OneParam_Int(environment);
+            var m = _type.GetMethod(".ctor", tlist);
+            methodCache[token.GetHashCode()] = m;
+            return m;
+        }
+        IField GetField(object token)
+        {
+            IField __field = null;
+            if (fieldCache.TryGetValue(token.GetHashCode(), out __field))
+            {
+                return __field;
+            }
+            if (token is Mono.Cecil.FieldDefinition)
+            {
+                Mono.Cecil.FieldDefinition field = token as Mono.Cecil.FieldDefinition;
+                var type = GetType(field.DeclaringType.FullName);
+                __field = type.GetField(field.Name);
+
+
+
+            }
+            else if (token is Mono.Cecil.FieldReference)
+            {
+                Mono.Cecil.FieldReference field = token as Mono.Cecil.FieldReference;
+                var type = GetType(field.DeclaringType.FullName);
+                __field = type.GetField(field.Name);
+
+
+            }
+            //else if(token is CLRSharp_Instance)
+            // {
+            //CLRSharp_Instance inst = token as CLRSharp_Instance;
+            //return inst.Fields[field.Name];
+            // }
+
+            else
+            {
+                throw new NotImplementedException("不可处理的token" + token.GetType().ToString());
+            }
+            fieldCache[token.GetHashCode()] = __field;
+            return __field;
+        }
+        object GetToken(object token)
+        {
+            if (token is Mono.Cecil.FieldDefinition || token is Mono.Cecil.FieldReference)
+            {
+
+                return GetField(token);
+
+            }
+
+            else if (token is Mono.Cecil.TypeDefinition || token is Mono.Cecil.TypeReference)
+            {
+                return GetType(token);
+            }
+            else
+            {
+                throw new NotImplementedException("不可处理的token" + token.GetType().ToString());
+            }
+        }
+        int GetParamPos(object token)
+        {
+            if (token is byte)
+            {
+                return (byte)token;
+            }
+            else if (token is sbyte)
+            {
+                return (sbyte)token;
+            }
+            else if (token is int)
+            {
+                return (int)token;
+            }
+            else if (token is Mono.Cecil.ParameterReference)
+            {
+                int i = (token as Mono.Cecil.ParameterReference).Index;
+                if (this.stacks.Peek().Name == ".ctor" || this.stacks.Peek().IsStatic == false)
+                {
+                    i++;
+                }
+                return i;
+            }
+            else
+            {
+                throw new NotImplementedException();
+            }
+        }
+        int GetBaseCount(Type _now, Type _base)
+        {
+            if (_now == _base)
+                return 0;
+            if (_now.IsSubclassOf(_base) == false)
+            {
+                return -1;
+            }
+            return GetBaseCount(_now.BaseType, _base) + 1;
+        }
+        bool JumpToErr(CodeBody body, StackFrame frame, Exception err)
+        {
+            var posnow = frame._pos;
+            List<Mono.Cecil.Cil.ExceptionHandler> ehs = new List<ExceptionHandler>();
+            Mono.Cecil.Cil.ExceptionHandler ehNear = null;
+            int ehNearB = -1;
+            foreach (var eh in body.bodyNative.ExceptionHandlers)
+            {
+                if (eh.HandlerType == ExceptionHandlerType.Catch)
+                {
+                    Type ehtype = GetType(eh.CatchType).TypeForSystem;
+                    if (ehtype == err.GetType() || err.GetType().IsSubclassOf(ehtype))
+                    //if(GetType(eh.CatchType)== environment.GetType(err.GetType()))
+                    {
+                        if (eh.TryStart.Offset <= posnow.Offset && eh.TryEnd.Offset >= posnow.Offset)
+                        {
+                            if (ehNear == null)
+                            {
+                                ehNear = eh;//第一个
+                                ehNearB = GetBaseCount(ehtype, err.GetType());
+                            }
+                            else
+                            {
+                                if (eh.TryStart.Offset > ehNear.TryStart.Offset || eh.TryEnd.Offset < ehNear.TryEnd.Offset)//范围更小
+                                {
+                                    ehNear = eh;
+                                    ehNearB = GetBaseCount(ehtype, err.GetType());
+                                }
+                                else if (eh.TryStart.Offset == ehNear.TryStart.Offset || eh.TryEnd.Offset == ehNear.TryEnd.Offset)//范围相等
+                                {
+                                    if (ehtype == err.GetType())//类型一致,没有比这个更牛的了
+                                    {
+                                        ehNear = eh;
+                                        ehNearB = GetBaseCount(ehtype, err.GetType());
+                                    }
+                                    else if (GetType(ehNear.CatchType).TypeForSystem == err.GetType())//上次找到的就是第一,不用比了
+                                    {
+                                        continue;
+                                    }
+                                    else //比较上次找到的类型,和这次找到的类型的亲缘性;
+                                    {
+                                        int newehNearB = GetBaseCount(ehtype, err.GetType());
+                                        if (newehNearB == -1) continue;
+                                        if (newehNearB < ehNearB)
+                                        {
+                                            ehNear = eh;
+                                            ehNearB = newehNearB;
+                                        }
+                                    }
+                                }
+                            }
+                            ehs.Add(eh);
+                        }
+                    }
+
+                }
+            }
+            if (ehNear != null)
+            {
+                frame.Ldobj(this, err);
+                frame._pos = ehNear.HandlerStart;
+                RunCodeWithTry(body, frame);
+                return true;
+            }
+            return false;
+        }
+
+        void RunCode(StackFrame stack, CodeBody body)
+        {
+            Mono.Collections.Generic.Collection<Mono.Cecil.Cil.Instruction> codes = body.bodyNative.Instructions;
+            while (true)
+            {
+                var code = stack._pos;
+                if (DebugLevel >= 9)
+                {
+                    environment.logger.Log(code.ToString());
+                }
+                switch (code.OpCode.Code)
+                {
+
+                    ///////////
+                    //流程控制
+
+                    case Code.Nop:
+                        stack.Nop();
+                        break;
+                    case Code.Ret:
+                        stack.Ret();
+                        return;
+                    case Code.Leave:
+                        stack.Leave(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Leave_S:
+                        //stack.Ret();
+                        stack.Leave(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    //流程控制之goto
+                    case Code.Br:
+                        stack.Br(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Br_S:
+                        stack.Br(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Brtrue:
+                        stack.Brtrue(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Brtrue_S:
+                        stack.Brtrue(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Brfalse:
+                        stack.Brfalse(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Brfalse_S:
+                        stack.Brfalse(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+
+                    //比较流程控制
+                    case Code.Beq:
+                        stack.Beq(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Beq_S:
+                        stack.Beq(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Bne_Un:
+                        stack.Bne_Un(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Bne_Un_S:
+                        stack.Bne_Un(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Bge:
+                        stack.Bge(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Bge_S:
+                        stack.Bge(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Bge_Un:
+                        stack.Bge_Un(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Bge_Un_S:
+                        stack.Bge_Un(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Bgt:
+                        stack.Bgt(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Bgt_S:
+                        stack.Bgt(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Bgt_Un:
+                        stack.Bgt_Un(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Bgt_Un_S:
+                        stack.Bge_Un(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Ble:
+                        stack.Ble(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Ble_S:
+                        stack.Ble(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Ble_Un:
+                        stack.Ble_Un(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Ble_Un_S:
+                        stack.Ble_Un(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Blt:
+                        stack.Blt(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Blt_S:
+                        stack.Blt(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Blt_Un:
+                        stack.Blt_Un(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    case Code.Blt_Un_S:
+                        stack.Ble_Un(code.Operand as Mono.Cecil.Cil.Instruction);
+                        break;
+                    //逻辑计算
+                    case Code.Ceq:
+                        stack.Ceq();
+                        break;
+                    case Code.Cgt:
+                        stack.Cgt();
+                        break;
+                    case Code.Cgt_Un:
+                        stack.Cgt_Un();
+                        break;
+                    case Code.Clt:
+                        stack.Clt();
+                        break;
+                    case Code.Clt_Un:
+                        stack.Clt_Un();
+                        break;
+                    case Code.Ckfinite:
+                        stack.Ckfinite();
+                        break;
+                    //常量加载
+                    case Code.Ldc_I4:
+                        stack.Ldc_I4((int)Convert.ToDecimal(code.Operand));
+                        break;
+                    case Code.Ldc_I4_S:
+                        stack.Ldc_I4((int)Convert.ToDecimal(code.Operand));
+                        break;
+                    case Code.Ldc_I4_M1:
+                        stack.Ldc_I4(-1);
+                        break;
+                    case Code.Ldc_I4_0:
+                        stack.Ldc_I4(0);
+                        break;
+                    case Code.Ldc_I4_1:
+                        stack.Ldc_I4(1);
+                        break;
+                    case Code.Ldc_I4_2:
+                        stack.Ldc_I4(2);
+                        break;
+                    case Code.Ldc_I4_3:
+                        stack.Ldc_I4(3);
+                        break;
+                    case Code.Ldc_I4_4:
+                        stack.Ldc_I4(4);
+                        break;
+                    case Code.Ldc_I4_5:
+                        stack.Ldc_I4(5);
+                        break;
+                    case Code.Ldc_I4_6:
+                        stack.Ldc_I4(6);
+                        break;
+                    case Code.Ldc_I4_7:
+                        stack.Ldc_I4(7);
+                        break;
+                    case Code.Ldc_I4_8:
+                        stack.Ldc_I4(8);
+                        break;
+                    case Code.Ldc_I8:
+                        stack.Ldc_I8((Int64)(Convert.ToDecimal(code.Operand)));
+                        break;
+                    case Code.Ldc_R4:
+                        stack.Ldc_R4((float)(Convert.ToDecimal(code.Operand)));
+                        break;
+                    case Code.Ldc_R8:
+                        stack.Ldc_R8((double)(Convert.ToDecimal(code.Operand)));
+                        break;
+
+                    //定义为临时变量
+                    case Code.Stloc:
+                        stack.Stloc((int)code.Operand);
+                        break;
+                    case Code.Stloc_S:
+                        stack.Stloc(((VariableDefinition)code.Operand).Index);
+                        break;
+                    case Code.Stloc_0:
+                        stack.Stloc(0);
+                        break;
+                    case Code.Stloc_1:
+                        stack.Stloc(1);
+                        break;
+                    case Code.Stloc_2:
+                        stack.Stloc(2);
+                        break;
+                    case Code.Stloc_3:
+                        stack.Stloc(3);
+                        break;
+                    //从临时变量加载
+                    case Code.Ldloc:
+                        stack.Ldloc((int)code.Operand);
+                        break;
+                    case Code.Ldloc_S:
+                        stack.Ldloc(((VariableDefinition)code.Operand).Index);
+                        break;
+                    case Code.Ldloc_0:
+                        stack.Ldloc(0);
+                        break;
+                    case Code.Ldloc_1:
+                        stack.Ldloc(1);
+                        break;
+                    case Code.Ldloc_2:
+                        stack.Ldloc(2);
+                        break;
+                    case Code.Ldloc_3:
+                        stack.Ldloc(3);
+                        break;
+                    case Code.Ldloca:
+                        stack.Ldloca(((VariableDefinition)code.Operand).Index);
+                        break;
+                    case Code.Ldloca_S:
+                        stack.Ldloca(((VariableDefinition)code.Operand).Index);
+                        break;
+                    //加载字符串
+                    case Code.Ldstr:
+                        stack.Ldstr(code.Operand as string);
+                        break;
+                    //呼叫函数
+                    case Code.Call:
+                        stack.Call(this, GetMethod(code.Operand), false);
+                        break;
+                    case Code.Callvirt:
+                        stack.Call(this, GetMethod(code.Operand), true);
+                        break;
+                    //算术指令
+                    case Code.Add:
+                        stack.Add();
+                        break;
+                    case Code.Sub:
+                        stack.Sub();
+                        break;
+                    case Code.Mul:
+                        stack.Mul();
+                        break;
+                    case Code.Div:
+                        stack.Div();
+                        break;
+                    case Code.Div_Un:
+                        stack.Div_Un();
+                        break;
+                    case Code.Rem:
+                        stack.Rem();
+                        break;
+                    case Code.Rem_Un:
+                        stack.Rem_Un();
+                        break;
+                    case Code.Neg:
+                        stack.Neg();
+                        break;
+
+                    //装箱
+                    case Code.Box:
+                        stack.Box(GetType(code.Operand));
+                        break;
+                    case Code.Unbox:
+                        stack.Unbox();
+                        break;
+                    case Code.Unbox_Any:
+                        stack.Unbox_Any();
+                        break;
+
+                    //加载参数
+                    case Code.Ldarg:
+                        stack.Ldarg((int)code.Operand);
+                        break;
+                    case Code.Ldarg_S:
+                        stack.Ldarg(GetParamPos(code.Operand));
+                        break;
+                    case Code.Ldarg_0:
+                        stack.Ldarg(0);
+                        break;
+                    case Code.Ldarg_1:
+                        stack.Ldarg(1);
+                        break;
+                    case Code.Ldarg_2:
+                        stack.Ldarg(2);
+                        break;
+                    case Code.Ldarg_3:
+                        stack.Ldarg(3);
+                        break;
+                    //转换
+                    case Code.Conv_I1:
+                        stack.Conv_I1();
+                        break;
+                    case Code.Conv_U1:
+                        stack.Conv_U1();
+                        break;
+                    case Code.Conv_I2:
+                        stack.Conv_I2();
+                        break;
+                    case Code.Conv_U2:
+                        stack.Conv_U2();
+                        break;
+                    case Code.Conv_I4:
+                        stack.Conv_I4();
+                        break;
+                    case Code.Conv_U4:
+                        stack.Conv_U4();
+                        break;
+                    case Code.Conv_I8:
+                        stack.Conv_I8();
+                        break;
+                    case Code.Conv_U8:
+                        stack.Conv_U8();
+                        break;
+                    case Code.Conv_I:
+                        stack.Conv_I();
+                        break;
+                    case Code.Conv_U:
+                        stack.Conv_U();
+                        break;
+                    case Code.Conv_R4:
+                        stack.Conv_R4();
+                        break;
+                    case Code.Conv_R8:
+                        stack.Conv_R8();
+                        break;
+                    case Code.Conv_R_Un:
+                        stack.Conv_R_Un();
+                        break;
+                    case Code.Conv_Ovf_I1:
+                        stack.Conv_Ovf_I1();
+                        break;
+                    case Code.Conv_Ovf_U1:
+                        stack.Conv_Ovf_U1();
+                        break;
+                    case Code.Conv_Ovf_I2:
+                        stack.Conv_Ovf_I2();
+                        break;
+                    case Code.Conv_Ovf_U2:
+                        stack.Conv_Ovf_U2();
+                        break;
+                    case Code.Conv_Ovf_I4:
+                        stack.Conv_Ovf_I4();
+                        break;
+                    case Code.Conv_Ovf_U4:
+                        stack.Conv_Ovf_U4();
+                        break;
+
+                    case Code.Conv_Ovf_I8:
+                        stack.Conv_Ovf_I8();
+                        break;
+                    case Code.Conv_Ovf_U8:
+                        stack.Conv_Ovf_U8();
+                        break;
+                    case Code.Conv_Ovf_I:
+                        stack.Conv_Ovf_I();
+                        break;
+                    case Code.Conv_Ovf_U:
+                        stack.Conv_Ovf_U();
+                        break;
+                    case Code.Conv_Ovf_I1_Un:
+                        stack.Conv_Ovf_I1_Un();
+                        break;
+
+                    case Code.Conv_Ovf_U1_Un:
+                        stack.Conv_Ovf_U1_Un();
+                        break;
+                    case Code.Conv_Ovf_I2_Un:
+                        stack.Conv_Ovf_I2_Un();
+                        break;
+                    case Code.Conv_Ovf_U2_Un:
+                        stack.Conv_Ovf_U2_Un();
+                        break;
+                    case Code.Conv_Ovf_I4_Un:
+                        stack.Conv_Ovf_I4_Un();
+                        break;
+                    case Code.Conv_Ovf_U4_Un:
+                        stack.Conv_Ovf_U4_Un();
+                        break;
+
+                    case Code.Conv_Ovf_I8_Un:
+                        stack.Conv_Ovf_I8_Un();
+                        break;
+                    case Code.Conv_Ovf_U8_Un:
+                        stack.Conv_Ovf_U8_Un();
+                        break;
+                    case Code.Conv_Ovf_I_Un:
+                        stack.Conv_Ovf_I_Un();
+                        break;
+                    case Code.Conv_Ovf_U_Un:
+                        stack.Conv_Ovf_U_Un();
+                        break;
+                    //数组
+                    case Code.Newarr:
+                        stack.NewArr(this, GetNewForArray(code.Operand));
+                        break;
+                    case Code.Ldlen:
+                        stack.LdLen();
+                        break;
+                    case Code.Ldelema:
+                        stack.Ldelema(code.Operand);
+                        break;
+                    case Code.Ldelem_I1:
+                        stack.Ldelem_I1();
+                        break;
+                    case Code.Ldelem_U1:
+                        stack.Ldelem_U1();
+                        break;
+                    case Code.Ldelem_I2:
+                        stack.Ldelem_I2();
+                        break;
+                    case Code.Ldelem_U2:
+                        stack.Ldelem_U2();
+                        break;
+                    case Code.Ldelem_I4:
+                        stack.Ldelem_I4();
+                        break;
+                    case Code.Ldelem_U4:
+                        stack.Ldelem_U4();
+                        break;
+                    case Code.Ldelem_I8:
+                        stack.Ldelem_I8();
+                        break;
+                    case Code.Ldelem_I:
+                        stack.Ldelem_I();
+                        break;
+                    case Code.Ldelem_R4:
+                        stack.Ldelem_R4();
+                        break;
+                    case Code.Ldelem_R8:
+                        stack.Ldelem_R8();
+                        break;
+                    case Code.Ldelem_Ref:
+                        stack.Ldelem_Ref();
+                        break;
+                    case Code.Ldelem_Any:
+                        stack.Ldelem_Any(code.Operand);
+                        break;
+
+                    case Code.Stelem_I:
+                        stack.Stelem_I();
+                        break;
+                    case Code.Stelem_I1:
+                        stack.Stelem_I1();
+                        break;
+                    case Code.Stelem_I2:
+                        stack.Stelem_I2();
+                        break;
+                    case Code.Stelem_I4:
+                        stack.Stelem_I4();
+                        break;
+                    case Code.Stelem_I8:
+                        stack.Stelem_I8();
+                        break;
+                    case Code.Stelem_R4:
+                        stack.Stelem_R4();
+                        break;
+                    case Code.Stelem_R8:
+                        stack.Stelem_R8();
+                        break;
+                    case Code.Stelem_Ref:
+                        stack.Stelem_Ref();
+                        break;
+                    case Code.Stelem_Any:
+                        stack.Stelem_Any();
+                        break;
+
+                    case Code.Newobj:
+                        stack.NewObj(this, GetMethod(code.Operand));
+                        break;
+
+                    case Code.Dup:
+                        stack.Dup();
+                        break;
+                    case Code.Pop:
+                        stack.Pop();
+                        break;
+
+                    case Code.Ldfld:
+                        stack.Ldfld(this, GetField(code.Operand));
+                        break;
+                    case Code.Ldflda:
+                        stack.Ldflda(this, GetField(code.Operand));
+                        break;
+                    case Code.Ldsfld:
+                        stack.Ldsfld(this, GetField(code.Operand));
+                        break;
+                    case Code.Ldsflda:
+                        stack.Ldsflda(this, GetField(code.Operand));
+                        break;
+                    case Code.Stfld:
+                        stack.Stfld(this, GetField(code.Operand));
+                        break;
+                    case Code.Stsfld:
+                        stack.Stsfld(this, GetField(code.Operand));
+                        break;
+
+
+                    case Code.Constrained:
+                        stack.Constrained(this, GetType(code.Operand));
+                        break;
+
+                    case Code.Isinst:
+                        stack.Isinst(this, GetType(code.Operand));
+                        break;
+                    case Code.Ldtoken:
+                        stack.Ldtoken(this, GetToken(code.Operand));
+                        break;
+
+                    case Code.Ldftn:
+                        stack.Ldftn(this, GetMethod(code.Operand));
+                        break;
+                    case Code.Ldvirtftn:
+                        stack.Ldvirtftn(this, GetMethod(code.Operand));
+                        break;
+                    case Code.Ldarga:
+                        stack.Ldarga(this, code.Operand);
+                        break;
+                    case Code.Ldarga_S:
+                        stack.Ldarga(this, code.Operand);
+                        break;
+                    case Code.Calli:
+                        stack.Calli(this, code.Operand);
+                        break;
+                    ///下面是还没有处理的指令
+                    case Code.Break:
+                        stack.Break(this, code.Operand);
+                        break;
+                    case Code.Starg_S:
+                        stack.Starg_S(this, code.Operand);
+                        break;
+                    case Code.Ldnull:
+                        stack.Ldnull();
+                        break;
+                    case Code.Jmp:
+                        stack.Jmp(this, code.Operand);
+                        break;
+                    case Code.Switch:
+                        stack.Switch(this, code.Operand as Mono.Cecil.Cil.Instruction[]);
+                        break;
+                    case Code.Ldind_I1:
+                        stack.Ldind_I1(this, code.Operand);
+                        break;
+                    case Code.Ldind_U1:
+                        stack.Ldind_U1(this, code.Operand);
+                        break;
+                    case Code.Ldind_I2:
+                        stack.Ldind_I2(this, code.Operand);
+                        break;
+                    case Code.Ldind_U2:
+                        stack.Ldind_U2(this, code.Operand);
+                        break;
+                    case Code.Ldind_I4:
+                        stack.Ldind_I4(this, code.Operand);
+                        break;
+                    case Code.Ldind_U4:
+                        stack.Ldind_U4(this, code.Operand);
+                        break;
+                    case Code.Ldind_I8:
+                        stack.Ldind_I8(this, code.Operand);
+                        break;
+                    case Code.Ldind_I:
+                        stack.Ldind_I(this, code.Operand);
+                        break;
+                    case Code.Ldind_R4:
+                        stack.Ldind_R4(this, code.Operand);
+                        break;
+                    case Code.Ldind_R8:
+                        stack.Ldind_R8(this, code.Operand);
+                        break;
+                    case Code.Ldind_Ref:
+                        stack.Ldind_Ref(this, code.Operand);
+                        break;
+                    case Code.Stind_Ref:
+                        stack.Stind_Ref(this, code.Operand);
+                        break;
+                    case Code.Stind_I1:
+                        stack.Stind_I1(this, code.Operand);
+                        break;
+                    case Code.Stind_I2:
+                        stack.Stind_I2(this, code.Operand);
+                        break;
+                    case Code.Stind_I4:
+                        stack.Stind_I4(this, code.Operand);
+                        break;
+                    case Code.Stind_I8:
+                        stack.Stind_I8(this, code.Operand);
+                        break;
+                    case Code.Stind_R4:
+                        stack.Stind_R4(this, code.Operand);
+                        break;
+                    case Code.Stind_R8:
+                        stack.Stind_R8(this, code.Operand);
+                        break;
+                    case Code.And:
+                        stack.And(this, code.Operand);
+                        break;
+                    case Code.Or:
+                        stack.Or(this, code.Operand);
+                        break;
+                    case Code.Xor:
+                        stack.Xor(this, code.Operand);
+                        break;
+                    case Code.Shl:
+                        stack.Shl(this, code.Operand);
+                        break;
+                    case Code.Shr:
+                        stack.Shr(this, code.Operand);
+                        break;
+                    case Code.Shr_Un:
+                        stack.Shr_Un(this, code.Operand);
+                        break;
+                    case Code.Not:
+                        stack.Not(this, code.Operand);
+                        break;
+                    case Code.Cpobj:
+                        stack.Cpobj(this, code.Operand);
+                        break;
+                    case Code.Ldobj:
+                        stack.Ldobj(this, code.Operand);
+                        break;
+                    case Code.Castclass:
+                        stack.Castclass(this, code.Operand);
+                        break;
+                    case Code.Throw:
+                        stack.Throw(this, code.Operand);
+                        break;
+                    case Code.Stobj:
+                        stack.Stobj(this, code.Operand);
+                        break;
+                    case Code.Refanyval:
+                        stack.Refanyval(this, code.Operand);
+                        break;
+                    case Code.Mkrefany:
+                        stack.Mkrefany(this, code.Operand);
+                        break;
+
+                    case Code.Add_Ovf:
+                        stack.Add_Ovf(this, code.Operand);
+                        break;
+                    case Code.Add_Ovf_Un:
+                        stack.Add_Ovf_Un(this, code.Operand);
+                        break;
+                    case Code.Mul_Ovf:
+                        stack.Mul_Ovf(this, code.Operand);
+                        break;
+                    case Code.Mul_Ovf_Un:
+                        stack.Mul_Ovf_Un(this, code.Operand);
+                        break;
+                    case Code.Sub_Ovf:
+                        stack.Sub_Ovf(this, code.Operand);
+                        break;
+                    case Code.Sub_Ovf_Un:
+                        stack.Sub_Ovf_Un(this, code.Operand);
+                        break;
+                    case Code.Endfinally:
+                        stack.Endfinally(this, code.Operand);
+                        break;
+                    case Code.Stind_I:
+                        stack.Stind_I(this, code.Operand);
+                        break;
+                    case Code.Arglist:
+                        stack.Arglist(this, code.Operand);
+                        break;
+
+                    case Code.Starg:
+                        stack.Starg(this, code.Operand);
+                        break;
+                    case Code.Localloc:
+                        stack.Localloc(this, code.Operand);
+                        break;
+                    case Code.Endfilter:
+                        stack.Endfilter(this, code.Operand);
+                        break;
+                    case Code.Unaligned:
+                        stack.Unaligned(this, code.Operand);
+                        break;
+                    case Code.Volatile:
+                        stack.Volatile(this, code.Operand);
+                        break;
+                    case Code.Tail:
+                        stack.Tail(this, code.Operand);
+                        break;
+                    case Code.Initobj:
+                        stack.Initobj(this, this.GetType(code.Operand));
+                        break;
+                    case Code.Cpblk:
+                        stack.Cpblk(this, code.Operand);
+                        break;
+                    case Code.Initblk:
+                        stack.Initblk(this, code.Operand);
+                        break;
+                    case Code.No:
+                        stack.No(this, code.Operand);
+                        break;
+                    case Code.Rethrow:
+                        stack.Rethrow(this, code.Operand);
+                        break;
+                    case Code.Sizeof:
+                        stack.Sizeof(this, code.Operand);
+                        break;
+                    case Code.Refanytype:
+                        stack.Refanytype(this, code.Operand);
+                        break;
+                    case Code.Readonly:
+                        stack.Readonly(this, code.Operand);
+                        break;
+                    default:
+                        throw new Exception("未实现的OpCode:" + code.OpCode.Code);
+                }
+            }
+
+        }
+    }
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/Execute/Context.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 1ad2b77eb562cc54ca2f9ce00260d012
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 2273 - 0
Unity/Assets/Plugins/CLRSharp/Execute/StackFrame.cs

@@ -0,0 +1,2273 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    public class RefFunc
+    {
+        public IMethod _method;
+        public object _this;
+        public RefFunc(IMethod _method, object _this)
+        {
+            this._method = _method;
+            this._this = _this;
+        }
+    }
+    /// <summary>
+    /// 堆栈帧
+    /// 一个堆栈帧,包含一个计算栈,一个临时变量槽,一个参数槽
+    /// 模拟虚拟机上的堆栈帧
+    /// </summary>
+    public class StackFrame
+    {
+        public string Name
+        {
+            get;
+            private set;
+        }
+        public bool IsStatic
+        {
+            get;
+            private set;
+        }
+        public StackFrame(string name, bool isStatic)
+        {
+            this.Name = name;
+            this.IsStatic = IsStatic;
+        }
+        public Mono.Cecil.Cil.Instruction _pos = null;
+
+        public class MyCalcStack : Stack<object>
+        {
+            Queue<VBox> unused = new Queue<VBox>();
+            public void Push(VBox box)
+            {
+                if (box != null)
+                {
+                    box.refcount++;
+                    while (unused.Count > 0)
+                    {
+                        VBox b = unused.Dequeue();
+                        if (b.refcount == 0)
+                            ValueOnStack.UnUse(b);
+                    }
+                }
+                base.Push(box);
+            }
+            public new object Pop()
+            {
+                var ob = base.Pop();
+                VBox box = ob as VBox;
+                if (box != null)
+                {
+                    box.refcount--;
+                    if (box.refcount == 0)
+                        unused.Enqueue(box);
+                }
+                return ob;
+
+            }
+            public void ClearVBox()
+            {
+                while (unused.Count > 0)
+                {
+                    VBox b = unused.Dequeue();
+                    if (b.refcount == 0)
+                    {
+                        ValueOnStack.UnUse(b);
+                    }
+                    else
+                    {
+                        Console.WriteLine("not zero.");
+                    }
+                }
+                this.Clear();
+            }
+        }
+        public MyCalcStack stackCalc = new MyCalcStack();
+        public class MySlotVar : List<object>
+        {
+            public new void Add(object obj)
+            {
+                base.Add(obj);
+            }
+            public void Add(VBox box)
+            {
+                if (box != null)
+                {
+                    box.refcount++;
+                }
+                base.Add(box);
+            }
+            public void ClearVBox()
+            {
+                foreach (object b in this)
+                {
+                    VBox box = b as VBox;
+                    if (box != null)
+                    {
+                        box.refcount--;
+                        if (box.refcount == 0)
+                        {
+                            ValueOnStack.UnUse(box);
+                        }
+                        else
+                        {
+                            Console.WriteLine("not zero.");
+                        }
+                    }
+                }
+                this.Clear();
+            }
+        }
+        public MySlotVar slotVar = new MySlotVar();
+        public object[] _params = null;
+        public void SetParams(object[] _p)
+        {
+            _params = _p;
+        }
+        CodeBody _body = null;
+        public CodeBody codebody
+        {
+            get
+            {
+                return _body;
+            }
+        }
+        public void Init(CodeBody body)
+        {
+            _body = body;
+            if (body.typelistForLoc != null)
+            {
+                for (int i = 0; i < body.typelistForLoc.Count; i++)
+                {
+                    ICLRType t = _body.typelistForLoc[i];
+
+                    slotVar.Add(ValueOnStack.MakeVBox(t));
+                }
+            }
+        }
+        public object Return()
+        {
+
+            this.slotVar.ClearVBox();
+            if (this.stackCalc.Count == 0) return null;
+            object ret = stackCalc.Pop();
+            this.stackCalc.ClearVBox();
+
+            return ret;
+        }
+        //流程控制
+        public void Call(ThreadContext context, IMethod _clrmethod, bool bVisual)
+        {
+
+            if (_clrmethod == null)//不想被执行的函数
+            {
+                _pos = _pos.Next;
+                return;
+            }
+
+            object[] _pp = null;
+            object _this = null;
+
+            if (_clrmethod.ParamList != null)
+            {
+                _pp = new object[_clrmethod.ParamList.Count];
+                for (int i = 0; i < _pp.Length; i++)
+                {
+                    var pp = stackCalc.Pop();
+                    if (pp is CLRSharp_Instance&&_clrmethod.ParamList[i].TypeForSystem!=typeof(CLRSharp_Instance))
+                    {
+                        var inst =pp as CLRSharp_Instance;
+
+                        var btype = inst.type.ContainBase(_clrmethod.ParamList[i].TypeForSystem);
+                        if (btype)
+                        {
+                            var CrossBind = context.environment.GetCrossBind(_clrmethod.ParamList[i].TypeForSystem);
+                            if (CrossBind != null)
+                            {
+                                pp = CrossBind.CreateBind(inst);
+                            }
+                            else
+                            {
+                                pp = (_this as CLRSharp_Instance).system_base;
+                                //如果没有绑定器,尝试直接使用System_base;
+                            }
+                            //context.environment.logger.Log("这里有一个需要映射的类型");
+                        }
+
+                    }
+                    if (pp is VBox)
+                    {
+                        pp = (pp as VBox).BoxDefine();
+                    }
+                    if ((pp is int) && (_clrmethod.ParamList[i].TypeForSystem != typeof(int) && _clrmethod.ParamList[i].TypeForSystem != typeof(object)))
+                    {
+                        var _vbox = ValueOnStack.MakeVBox(_clrmethod.ParamList[i]);
+                        if (_vbox != null)
+                        {
+                            _vbox.SetDirect(pp);
+                            pp = _vbox.BoxDefine();
+                        }
+                    }
+                    _pp[_pp.Length - 1 - i] = pp;
+                }
+            }
+
+
+            //if (method.HasThis)
+            if (!_clrmethod.isStatic)
+            {
+                _this = stackCalc.Pop();
+            }
+            if (_clrmethod.DeclaringType.FullName.Contains("System.Runtime.CompilerServices.RuntimeHelpers") && _clrmethod.Name.Contains("InitializeArray"))
+            {
+                _pos = _pos.Next;
+                return;
+            }
+            if (_clrmethod.DeclaringType.FullName.Contains("System.Type") && _clrmethod.Name.Contains("GetTypeFromHandle"))
+            {
+                stackCalc.Push(_pp[0]);
+                _pos = _pos.Next;
+                return;
+            }
+            if (_clrmethod.DeclaringType.FullName.Contains("System.Object") && _clrmethod.Name.Contains(".ctor"))
+            {//跳过这个没意义的构造
+                _pos = _pos.Next;
+                return;
+            }
+            if (_this is RefObj && _clrmethod.Name != ".ctor")
+            {
+                _this = (_this as RefObj).Get();
+
+            }
+            if (_this is VBox)
+            {
+                _this = (_this as VBox).BoxDefine();
+            }
+            bool bCross = (_this is CLRSharp_Instance && _clrmethod is IMethod_System);
+            object returnvar =  _clrmethod.Invoke(context, _this, _pp, bVisual);
+            if (bCross)
+            {
+                //这里究竟如何处理还需要再考虑
+                //returnvar = _clrmethod.Invoke(context, (_this as CLRSharp_Instance).system_base, _pp, bVisual);
+                if (_clrmethod.Name.Contains(".ctor"))
+                {
+                    (_this as CLRSharp_Instance).system_base = returnvar;
+                    returnvar = (_this);
+                }
+            }
+            else
+            {
+                //returnvar = _clrmethod.Invoke(context, _this, _pp, bVisual);
+            }
+
+
+            // bool breturn = false;
+            if (_clrmethod.ReturnType != null && _clrmethod.ReturnType.FullName != "System.Void")
+            {
+                if ((returnvar is VBox) == false)
+                {
+                    var type = ValueOnStack.MakeVBox(_clrmethod.ReturnType);
+                    if (type != null)
+                    {
+                        type.SetDirect(returnvar);
+                        returnvar = type;
+                    }
+                }
+                stackCalc.Push(returnvar);
+            }
+
+            else if (_this is RefObj && _clrmethod.Name == ".ctor")
+            {
+                //如果这里有发生程序类型,脚本类型的cross,就需要特别处理
+                (_this as RefObj).Set(returnvar);
+            }
+            _pos = _pos.Next;
+            return;
+
+        }
+        //栈操作
+        public void Nop()
+        {
+            _pos = _pos.Next;
+        }
+        public void Dup()
+        {
+            stackCalc.Push(stackCalc.Peek());
+            _pos = _pos.Next;
+        }
+        public void Pop()
+        {
+            stackCalc.Pop();
+            _pos = _pos.Next;
+        }
+        //流程控制
+        public void Ret()
+        {
+            _pos = _pos.Next;
+        }
+        public void Box(ICLRType type)
+        {
+            object obj = stackCalc.Pop();
+            VBox box = obj as VBox;
+            if (type.TypeForSystem.IsEnum)
+            {
+                int ev = 0;
+                if (box != null) ev = box.v32;
+                else ev = (int)obj;
+                obj = Enum.ToObject(type.TypeForSystem, ev);
+            }
+            else
+            {
+                if (box != null)
+                    obj = box.BoxDefine();
+            }
+            stackCalc.Push(obj);
+            _pos = _pos.Next;
+        }
+        public void Unbox()
+        {
+            object obj = stackCalc.Pop();
+            var box = ValueOnStack.MakeVBox(obj.GetType());
+            if (box != null)
+            {
+                box.SetDirect(obj);
+                stackCalc.Push(box);
+            }
+            else
+            {
+                stackCalc.Push(obj);
+            }
+            _pos = _pos.Next;
+        }
+        public void Unbox_Any()
+        {
+            _pos = _pos.Next;
+        }
+        public void Br(Mono.Cecil.Cil.Instruction pos)
+        {
+            _pos = pos;
+        }
+        public void Leave(Mono.Cecil.Cil.Instruction pos)
+        {
+            stackCalc.Clear();
+            _pos = pos;
+        }
+        public void Brtrue(Mono.Cecil.Cil.Instruction pos)
+        {
+            object obj = stackCalc.Pop();
+            bool b = false;
+            if (obj != null)
+            {
+                if (obj is VBox)
+                {
+                    VBox box = obj as VBox;
+                    b = box.ToBool();
+                }
+                else if (obj.GetType().IsClass)
+                {
+                    b = true;
+                }
+                else if (obj is bool)
+                {
+                    b = (bool)obj;
+                }
+                else
+                {
+                    b = Convert.ToDecimal(obj) > 0;
+                }
+            }
+            //decimal b = Convert.ToDecimal(stackCalc.Pop());
+            //bool b = (bool)stackCalc.Pop();
+            if (b)
+            {
+                _pos = pos;
+            }
+            else
+            {
+                _pos = _pos.Next;
+            }
+        }
+        public void Brfalse(Mono.Cecil.Cil.Instruction pos)
+        {
+            decimal b = Convert.ToDecimal(stackCalc.Pop());
+            if (b <= 0)
+            {
+                _pos = pos;
+            }
+            else
+            {
+                _pos = _pos.Next;
+            }
+        }
+        //条件跳转
+        public void Beq(Mono.Cecil.Cil.Instruction pos)
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            if (n1.logic_eq(n2))
+            {
+                _pos = _pos.Next;
+            }
+            else
+            {
+                _pos = pos;
+            }
+        }
+        public void Bne(Mono.Cecil.Cil.Instruction pos)
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            if (n1.logic_ne(n2))
+            {
+                _pos = _pos.Next;
+            }
+            else
+            {
+                _pos = pos;
+            }
+        }
+        public void Bne_Un(Mono.Cecil.Cil.Instruction pos)
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            if (n1.logic_ne_Un(n2))
+            {
+                _pos = _pos.Next;
+            }
+            else
+            {
+                _pos = pos;
+            }
+        }
+        public void Bge(Mono.Cecil.Cil.Instruction pos)
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            if (n1.logic_ge(n2))
+            {
+                _pos = _pos.Next;
+            }
+            else
+            {
+                _pos = pos;
+            }
+        }
+        public void Bge_Un(Mono.Cecil.Cil.Instruction pos)
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            if (n1.logic_ge_Un(n2))
+            {
+                _pos = _pos.Next;
+            }
+            else
+            {
+                _pos = pos;
+            }
+        }
+        public void Bgt(Mono.Cecil.Cil.Instruction pos)
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            if (n1.logic_gt(n2))
+            {
+                _pos = _pos.Next;
+            }
+            else
+            {
+                _pos = pos;
+            }
+        }
+        public void Bgt_Un(Mono.Cecil.Cil.Instruction pos)
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            if (n1.logic_gt_Un(n2))
+            {
+                _pos = _pos.Next;
+            }
+            else
+            {
+                _pos = pos;
+            }
+        }
+        public void Ble(Mono.Cecil.Cil.Instruction pos)
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            if (n1.logic_le(n2))
+            {
+                _pos = _pos.Next;
+            }
+            else
+            {
+                _pos = pos;
+            }
+        }
+        public void Ble_Un(Mono.Cecil.Cil.Instruction pos)
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            if (n1.logic_le_Un(n2))
+            {
+                _pos = _pos.Next;
+            }
+            else
+            {
+                _pos = pos;
+            }
+        }
+        public void Blt(Mono.Cecil.Cil.Instruction pos)
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            if (n1.logic_lt(n2))
+            {
+                _pos = _pos.Next;
+            }
+            else
+            {
+                _pos = pos;
+            }
+        }
+        public void Blt_Un(Mono.Cecil.Cil.Instruction pos)
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            if (n1.logic_lt_Un(n2))
+            {
+                _pos = _pos.Next;
+            }
+            else
+            {
+                _pos = pos;
+            }
+        }
+        //加载常量
+        public void Ldc_I4(int v)//int32
+        {
+            VBox box = ValueOnStack.MakeVBox(NumberType.INT32);
+            box.v32 = v;
+            stackCalc.Push(box);
+            _pos = _pos.Next;
+
+        }
+
+        public void Ldc_I8(Int64 v)//int64
+        {
+            VBox box = ValueOnStack.MakeVBox(NumberType.INT64);
+            box.v64 = v;
+            stackCalc.Push(box);
+            _pos = _pos.Next;
+        }
+        public void Ldc_R4(float v)
+        {
+            VBox box = ValueOnStack.MakeVBox(NumberType.FLOAT);
+            box.vDF = v;
+            stackCalc.Push(box);
+            _pos = _pos.Next;
+        }
+        public void Ldc_R8(double v)
+        {
+            VBox box = ValueOnStack.MakeVBox(NumberType.DOUBLE);
+            box.vDF = v;
+            stackCalc.Push(box);
+            _pos = _pos.Next;
+        }
+        //放进变量槽
+        public void Stloc(int pos)
+        {
+            object v = stackCalc.Pop();
+            while (slotVar.Count <= pos)
+            {
+                slotVar.Add(null);
+            }
+            VBox box = slotVar[pos] as VBox;
+            if (box == null)
+            {
+                slotVar[pos] = v;
+            }
+            else
+            {
+                if (v is VBox)
+                    box.Set(v as VBox);
+                else
+                    box.SetDirect(v);
+            }
+            _pos = _pos.Next;
+        }
+        //拿出变量槽
+        public void Ldloc(int pos)
+        {
+            var obj = slotVar[pos];
+            VBox b = obj as VBox;
+            if (b != null)
+            {
+                obj = b.Clone();
+            }
+            stackCalc.Push(obj);
+            _pos = _pos.Next;
+        }
+        public enum RefType
+        {
+            loc,//本地变量槽
+            arg,//参数槽
+            field//成员变量
+        }
+        public class RefObj
+        {
+            public StackFrame frame;
+            public int pos;
+            public RefType type;
+            //public ICLRType _clrtype;
+            public IField _field;
+            public object _this;
+            public RefObj(StackFrame frame, int pos, RefType type)
+            {
+                this.frame = frame;
+                this.pos = pos;
+                this.type = type;
+            }
+            public RefObj(IField field, object _this)
+            {
+                this.type = RefType.field;
+                //this._clrtype = type;
+                this._field = field;
+                this._this = _this;
+            }
+
+            public void Set(object obj)
+            {
+                if (type == RefType.arg)
+                {
+                    frame._params[pos] = obj;
+                }
+                else if (type == RefType.loc)
+                {
+                    while (frame.slotVar.Count <= pos)
+                    {
+                        frame.slotVar.Add(null);
+                    }
+                    frame.slotVar[pos] = obj;
+                }
+                else if (type == RefType.field)
+                {
+                    _field.Set(_this, obj);
+                }
+
+            }
+            public object Get()
+            {
+                if (type == RefType.arg)
+                {
+                    return frame._params[pos];
+                }
+                else if (type == RefType.loc)
+                {
+                    while (frame.slotVar.Count <= pos)
+                    {
+                        frame.slotVar.Add(null);
+                    }
+                    return frame.slotVar[pos];
+                }
+                else if (type == RefType.field)
+                {
+                    return _field.Get(_this);
+                }
+                return null;
+            }
+
+        }
+
+        //拿出变量槽的引用
+
+        public void Ldloca(int pos)
+        {
+            stackCalc.Push(new RefObj(this, pos, RefType.loc));
+            _pos = _pos.Next;
+        }
+
+        public void Ldstr(string text)
+        {
+            stackCalc.Push(text);
+            _pos = _pos.Next;
+        }
+
+        //加载参数(还得处理static,il静态非静态不一样,成员参数0是this)
+        public void Ldarg(int pos)
+        {
+            object p = null;
+            if (_params != null)
+                p = _params[pos];
+            stackCalc.Push(p);
+            _pos = _pos.Next;
+        }
+        public void Ldarga(int pos)
+        {
+            stackCalc.Push(new RefObj(this, pos, RefType.arg));
+            _pos = _pos.Next;
+        }
+        //逻辑计算
+
+        public void Ceq()
+        {
+            var obj2 = stackCalc.Pop();
+            var obj1 = stackCalc.Pop();
+            VBox n2 = obj2 as VBox;
+            VBox n1 = obj1 as VBox;
+            bool beq = false;
+            if (n1 == null || n2 == null)
+            //if (obj1 == null || obj2 == null)
+            {
+                if (obj1 != null)
+                    beq = obj1.Equals(obj2);
+                else
+                    beq = (obj1 == obj2);
+            }
+            else
+            {
+                beq = n1.logic_eq(n2);
+            }
+
+
+
+            stackCalc.Push(ValueOnStack.MakeVBoxBool(beq));
+            _pos = _pos.Next;
+        }
+        public void Cgt()
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+
+            stackCalc.Push(ValueOnStack.MakeVBoxBool(n1.logic_gt(n2)));
+            _pos = _pos.Next;
+        }
+        public void Cgt_Un()
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+
+            stackCalc.Push(ValueOnStack.MakeVBoxBool(n1.logic_gt_Un(n2)));
+            _pos = _pos.Next;
+        }
+        public void Clt()
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+            stackCalc.Push(ValueOnStack.MakeVBoxBool(n1.logic_lt(n2)));
+            _pos = _pos.Next;
+        }
+        public void Clt_Un()
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+            stackCalc.Push(ValueOnStack.MakeVBoxBool(n1.logic_lt_Un(n2)));
+            _pos = _pos.Next;
+        }
+        public void Ckfinite()
+        {
+            object n1 = stackCalc.Pop();
+            if (n1 is float)
+            {
+                float v = (float)n1;
+                stackCalc.Push(float.IsInfinity(v) || float.IsNaN(v) ? 1 : 0);
+            }
+            else
+            {
+                double v = (double)n1;
+                stackCalc.Push(double.IsInfinity(v) || double.IsNaN(v) ? 1 : 0);
+            }
+            _pos = _pos.Next;
+        }
+        //算术操作
+        public void Add()
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+            n1.Add(n2);
+            stackCalc.Push(n1);
+            _pos = _pos.Next;
+        }
+        public void Sub()
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+            n1.Sub(n2);
+            stackCalc.Push(n1);
+            _pos = _pos.Next;
+        }
+        public void Mul()
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+            n1.Mul(n2);
+            stackCalc.Push(n1);
+            _pos = _pos.Next;
+        }
+        public void Div()
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+            n1.Div(n2);
+            stackCalc.Push(n1);
+            _pos = _pos.Next;
+        }
+        public void Div_Un()
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+            n1.Div(n2);//!!! _un
+            stackCalc.Push(n1);
+            _pos = _pos.Next;
+        }
+        public void Rem()
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+            n1.Mod(n2);
+            stackCalc.Push(n1);
+            _pos = _pos.Next; ;
+        }
+        public void Rem_Un()
+        {
+            VBox n2 = stackCalc.Pop() as VBox;
+            VBox n1 = stackCalc.Pop() as VBox;
+            n1.Mod(n2);//!!!_un
+            stackCalc.Push(n1);
+            _pos = _pos.Next;
+        }
+        public void Neg()
+        {
+
+            object n1 = stackCalc.Pop();
+            if (n1 is int)
+            {
+                stackCalc.Push(~(int)n1);
+            }
+            else if (n1 is Int64)
+            {
+                stackCalc.Push(~(Int64)n1);
+            }
+            else
+            {
+                stackCalc.Push(n1);
+            }
+
+            _pos = _pos.Next;
+        }
+        //转换
+        public void Conv_I1()
+        {
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.SBYTE));
+            }
+            else
+            {
+                stackCalc.Push((sbyte)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_U1()
+        {
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.BYTE));
+            }
+            else
+            {
+                stackCalc.Push((byte)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_I2()
+        {
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.INT16));
+            }
+            else
+            {
+                stackCalc.Push((Int16)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_U2()
+        {
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.UINT16));
+            }
+            else
+            {
+                stackCalc.Push((UInt16)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_I4()
+        {
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.INT32));
+            }
+            else
+            {
+                stackCalc.Push((Int32)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_U4()
+        {
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.UINT32));
+            }
+            else
+            {
+                stackCalc.Push((UInt32)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_I8()
+        {
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.INT64));
+            }
+            else
+            {
+                stackCalc.Push((Int64)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_U8()
+        {
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.UINT64));
+            }
+            else
+            {
+                stackCalc.Push((UInt64)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_I()
+        {
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.INT32));
+            }
+            else
+            {
+                stackCalc.Push((Int32)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_U()
+        {
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.UINT32));
+            }
+            else
+            {
+                stackCalc.Push((UInt32)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_R4()
+        {
+
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.FLOAT));
+            }
+            else
+            {
+                stackCalc.Push((float)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_R8()
+        {
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.DOUBLE));
+            }
+            else
+            {
+                stackCalc.Push((double)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_R_Un()
+        {
+
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.FLOAT));
+            }
+            else
+            {
+                stackCalc.Push((float)num1);
+            }
+            _pos = _pos.Next;
+        }
+
+        ////数组
+        public void NewArr(ThreadContext context, IMethod newForArray)
+        {
+            //string typename = type.FullName + "[]";
+            //var _type = context.environment.GetType(typename, type.Module);
+            //MethodParamList tlist = MethodParamList.MakeList_OneParam_Int(context.environment);
+            //var m = _type.GetMethod(".ctor", tlist);
+            var objv = stackCalc.Pop();
+            if (objv is VBox) objv = (objv as VBox).BoxDefine();
+            var array = newForArray.Invoke(context, null, new object[] { objv });
+            stackCalc.Push(array);
+            _pos = _pos.Next;
+        }
+        public void LdLen()
+        {
+            var obj = stackCalc.Pop();
+            Array a = obj as Array;
+            var vbox = ValueOnStack.MakeVBox(NumberType.INT32);
+            vbox.v32 = a.Length;
+            stackCalc.Push(vbox);
+            _pos = _pos.Next;
+        }
+        public void Ldelema(object obj)
+        {
+            throw new NotImplementedException();
+            //_pos = _pos.Next;
+        }
+        public void Ldelem_I1()
+        {
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            Array array = stackCalc.Pop() as Array;
+            stackCalc.Push(array.GetValue(index));
+            _pos = _pos.Next;
+        }
+        public void Ldelem_U1()
+        {
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            Array array = stackCalc.Pop() as Array;
+            stackCalc.Push(array.GetValue(index));
+            _pos = _pos.Next;
+        }
+
+        public void Ldelem_I2()
+        {
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            Array array = stackCalc.Pop() as Array;
+            stackCalc.Push(array.GetValue(index));
+            _pos = _pos.Next;
+        }
+        public void Ldelem_U2()
+        {
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            Array array = stackCalc.Pop() as Array;
+            stackCalc.Push(array.GetValue(index));
+            _pos = _pos.Next;
+        }
+        public void Ldelem_I4()
+        {
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            Array array = stackCalc.Pop() as Array;
+            stackCalc.Push(array.GetValue(index));
+            _pos = _pos.Next;
+        }
+        public void Ldelem_U4()
+        {
+            int index = (int)stackCalc.Pop();
+            Array array = stackCalc.Pop() as Array;
+            stackCalc.Push(array.GetValue(index));
+            _pos = _pos.Next;
+        }
+
+        public void Ldelem_I8()
+        {
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            Array array = stackCalc.Pop() as Array;
+            stackCalc.Push(array.GetValue(index));
+            _pos = _pos.Next;
+        }
+        public void Ldelem_I()
+        {
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            Array array = stackCalc.Pop() as Array;
+            stackCalc.Push(array.GetValue(index));
+            _pos = _pos.Next;
+        }
+        public void Ldelem_R4()
+        {
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            Array array = stackCalc.Pop() as Array;
+            stackCalc.Push(array.GetValue(index));
+            _pos = _pos.Next;
+        }
+        public void Ldelem_R8()
+        {
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            Array array = stackCalc.Pop() as Array;
+            stackCalc.Push(array.GetValue(index));
+            _pos = _pos.Next;
+        }
+        public void Ldelem_Ref()
+        {
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            Array array = stackCalc.Pop() as Array;
+            stackCalc.Push(array.GetValue(index));
+            _pos = _pos.Next;
+        }
+        public void Ldelem_Any(object obj)
+        {
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            Object[] array = stackCalc.Pop() as Object[];
+            stackCalc.Push(array[index]);
+            _pos = _pos.Next;
+        }
+        public void Stelem_I()
+        {
+            var obj = stackCalc.Pop();
+            int value = 0;
+            if (obj is VBox)
+            {
+                value = (obj as VBox).ToInt();
+            }
+            else
+            {
+                value = (Int32)obj;
+            }
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            var array = stackCalc.Pop() as Int32[];
+            array[index] = value;
+            _pos = _pos.Next;
+        }
+        public void Stelem_I1()
+        {
+            var obj = stackCalc.Pop();
+            int value = 0;
+            if (obj is VBox)
+            {
+                value = (obj as VBox).ToInt();
+            }
+            else
+            {
+                value = (sbyte)obj;
+            }
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            var array = stackCalc.Pop() as sbyte[];
+            array[index] = (sbyte)value;
+            _pos = _pos.Next;
+        }
+        public void Stelem_I2()
+        {
+            var obj = stackCalc.Pop();
+            int value = 0;
+            if (obj is VBox)
+            {
+                value = (obj as VBox).ToInt();
+            }
+            else
+            {
+                value = (Int16)obj;
+            }
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            var array = stackCalc.Pop();
+            if (array is char[])
+            {
+                (array as char[])[index] = (char)value;
+            }
+            else if (array is Int16[])
+            {
+                (array as Int16[])[index] = (Int16)value;
+            }
+
+            _pos = _pos.Next;
+        }
+        public void Stelem_I4()
+        {
+            var obj = stackCalc.Pop();
+            int value = 0;
+            if (obj is VBox)
+            {
+                value = (obj as VBox).ToInt();
+            }
+            else
+            {
+                value = (Int32)obj;
+            }
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            var array = stackCalc.Pop() as Int32[];
+            array[index] = (Int32)value;
+            _pos = _pos.Next;
+        }
+        public void Stelem_I8()
+        {
+            var obj = stackCalc.Pop();
+            long value = 0;
+            if (obj is VBox)
+            {
+                value = (obj as VBox).ToInt64();
+            }
+            else
+            {
+                value = (Int64)obj;
+            }
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            var array = stackCalc.Pop() as Int64[];
+            array[index] = value;
+            _pos = _pos.Next;
+        }
+        public void Stelem_R4()
+        {
+            var obj = stackCalc.Pop();
+            float value = 0;
+            if (obj is VBox)
+            {
+                value = (obj as VBox).ToFloat();
+            }
+            else
+            {
+                value = (float)obj;
+            }
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            var array = stackCalc.Pop() as float[];
+            array[index] = value;
+            _pos = _pos.Next;
+        }
+        public void Stelem_R8()
+        {
+            var obj = stackCalc.Pop();
+            double value = 0;
+            if (obj is VBox)
+            {
+                value = (obj as VBox).ToDouble();
+            }
+            else
+            {
+                value = (double)obj;
+            }
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            var array = stackCalc.Pop() as double[];
+            array[index] = value;
+            _pos = _pos.Next;
+        }
+        public void Stelem_Ref()
+        {
+            var value = stackCalc.Pop();
+            var indexobj = stackCalc.Pop();
+            int index = 0;
+            if ((indexobj is VBox))
+            {
+                index = (indexobj as VBox).ToInt();
+            }
+            else
+            {
+                index = (int)indexobj;
+            }
+            var array = stackCalc.Pop() as Object[];
+
+            array[index] = value;
+            _pos = _pos.Next;
+        }
+
+        public void Stelem_Any()
+        {
+            var value = stackCalc.Pop();
+            var index = (int)stackCalc.Pop();
+            var array = stackCalc.Pop() as Object[];
+            array[index] = value;
+            _pos = _pos.Next;
+        }
+
+        //寻址类
+        public void NewObj(ThreadContext context, IMethod _clrmethod)
+        {
+            //MethodParamList list = new MethodParamList(context.environment, method);
+            object[] _pp = null;
+            if (_clrmethod.ParamList != null && _clrmethod.ParamList.Count > 0)
+            {
+                _pp = new object[_clrmethod.ParamList.Count];
+                for (int i = 0; i < _pp.Length; i++)
+                {
+                    var obj = stackCalc.Pop();
+                    if (obj is VBox)
+                    {
+                        obj = (obj as VBox).BoxDefine();
+                    }
+                    _pp[_pp.Length - 1 - i] = obj;
+                }
+            }
+            //var typesys = context.environment.GetType(method.DeclaringType.FullName, method.Module);
+            object returnvar = _clrmethod.Invoke(context, null, _pp);
+
+            stackCalc.Push(returnvar);
+
+            _pos = _pos.Next;
+        }
+        //public void NewObj(ThreadContext context, Mono.Cecil.MethodReference method)
+        //{
+        //    object[] _pp = null;
+        //    if (method.Parameters.Count > 0)
+        //    {
+        //        _pp = new object[method.Parameters.Count];
+        //        for (int i = 0; i < _pp.Length; i++)
+        //        {
+        //            _pp[_pp.Length - 1 - i] = stackCalc.Pop();
+        //        }
+        //    }
+        //    var typesys = context.environment.GetType(method.DeclaringType.FullName, method.Module);
+
+        //    MethodParamList list = new MethodParamList(context.environment, method);
+
+        //    object returnvar = typesys.GetMethod(method.Name, list).Invoke(context, null, _pp);
+
+        //    stackCalc.Push(returnvar);
+
+
+
+
+        //    _pos = _pos.Next;
+
+        //}
+        public void Ldfld(ThreadContext context, IField field)
+        {
+            var obj = stackCalc.Pop();
+
+            //var type = context.environment.GetType(field.DeclaringType.FullName, field.Module);
+            //ar ff = type.GetField(field.Name);
+            if (obj is RefObj)
+            {
+                obj = (obj as RefObj).Get();
+            }
+            var value = field.Get(obj);
+            VBox box = ValueOnStack.MakeVBox(field.FieldType);
+            if (box != null)
+            {
+                box.SetDirect(value);
+                value = box;
+            }
+            stackCalc.Push(value);
+            //System.Type t =obj.GetType();
+            _pos = _pos.Next;
+        }
+        public void Ldflda(ThreadContext context, IField field)
+        {
+            var obj = stackCalc.Pop();
+
+            // var type = context.environment.GetType(field.DeclaringType.FullName, field.Module);
+            //var ff = type.GetField(field.Name);
+
+            stackCalc.Push(new RefObj(field, obj));
+
+            _pos = _pos.Next;
+        }
+        public void Ldsfld(ThreadContext context, IField field)
+        {
+            //var type = context.environment.GetType(field.DeclaringType.FullName, field.Module);
+            //var ff = type.GetField(field.Name);
+            var value = field.Get(null);
+            VBox box = ValueOnStack.MakeVBox(field.FieldType);
+            if (box != null)
+            {
+                box.SetDirect(value);
+                value = box;
+            }
+            stackCalc.Push(value);
+            //System.Type t =obj.GetType();
+            _pos = _pos.Next;
+        }
+        public void Ldsflda(ThreadContext context, IField field)
+        {
+            //var type = context.environment.GetType(field.DeclaringType.FullName, field.Module);
+            //var ff = type.GetField(field.Name);
+
+            stackCalc.Push(new RefObj(field, null));
+
+            _pos = _pos.Next;
+        }
+        public void Stfld(ThreadContext context, IField field)
+        {
+            var value = stackCalc.Pop();
+
+            var obj = stackCalc.Pop();
+            //var type = context.environment.GetType(field.DeclaringType.FullName, field.Module);
+            //var ff = type.GetField(field.Name);
+            if (obj is RefObj)
+            {
+                var _this = (obj as RefObj).Get();
+                if (_this == null && !field.isStatic)
+                {
+                    (obj as RefObj).Set(field.DeclaringType.InitObj());
+                }
+                obj = (obj as RefObj).Get();
+            }
+            if (value is VBox)
+            {
+                value = (value as VBox).BoxDefine();
+            }
+            //else
+            {//某些类型需要转换。。。
+                VBox fbox = ValueOnStack.MakeVBox(field.FieldType);
+                if (fbox != null)
+                {
+                    fbox.SetDirect(value);
+                    value = fbox.BoxDefine();
+                }
+            }
+            field.Set(obj, value);
+            _pos = _pos.Next;
+        }
+        public void Stsfld(ThreadContext context, IField field)
+        {
+            var value = stackCalc.Pop();
+            //var obj = stackCalc.Pop();
+
+            if (value is VBox)
+            {
+                value = (value as VBox).BoxDefine();
+            }
+            //var type = context.environment.GetType(field.DeclaringType.FullName, field.Module);
+            //var ff = type.GetField(field.Name);
+            field.Set(null, value);
+
+            _pos = _pos.Next;
+        }
+        public void Constrained(ThreadContext context, ICLRType obj)
+        {
+
+            _pos = _pos.Next;
+        }
+        public void Isinst(ThreadContext context, ICLRType _type)
+        {
+            var value = stackCalc.Pop();
+            //var _type = context.environment.GetType(obj.FullName, obj.Module);
+            if (_type.IsInst(value))
+                stackCalc.Push(value);
+            else
+                stackCalc.Push(null);
+            _pos = _pos.Next;
+        }
+        public void Ldtoken(ThreadContext context, object token)
+        {
+            //string fname = obj.FullName;
+            //string tfname = obj.FieldType.FullName;
+            //var _type = context.environment.GetType(obj.DeclaringType.FullName, obj.Module);
+            //var field = _type.GetField(obj.Name);
+            stackCalc.Push(token);
+            _pos = _pos.Next;
+        }
+
+        public void Conv_Ovf_I1()
+        {
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.SBYTE));
+            }
+            else
+            {
+                stackCalc.Push((sbyte)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_Ovf_U1()
+        {
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.BYTE));
+            }
+            else
+            {
+                stackCalc.Push((byte)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_Ovf_I2()
+        {
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.INT16));
+            }
+            else
+            {
+                stackCalc.Push((Int16)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_Ovf_U2()
+        {
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.UINT16));
+            }
+            else
+            {
+                stackCalc.Push((Int16)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_Ovf_I4()
+        {
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.INT32));
+            }
+            else
+            {
+                stackCalc.Push((Int32)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_Ovf_U4()
+        {
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.UINT32));
+            }
+            else
+            {
+                stackCalc.Push((UInt32)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_Ovf_I8()
+        {
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.INT64));
+            }
+            else
+            {
+                stackCalc.Push((Int64)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_Ovf_U8()
+        {
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.UINT64));
+            }
+            else
+            {
+                stackCalc.Push((Int64)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_Ovf_I()
+        {
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.INT32));
+            }
+            else
+            {
+                stackCalc.Push((Int32)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_Ovf_U()
+        {
+            object num1 = stackCalc.Pop();
+            VBox b = num1 as VBox;
+            if (b != null)
+            {
+                stackCalc.Push(ValueOnStack.Convert(b, NumberType.UINT32));
+            }
+            else
+            {
+                stackCalc.Push((UInt32)num1);
+            }
+            _pos = _pos.Next;
+        }
+        public void Conv_Ovf_I1_Un()
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Conv_Ovf_U1_Un()
+        {
+            throw new NotImplementedException();
+        }
+        public void Conv_Ovf_I2_Un()
+        {
+            throw new NotImplementedException();
+        }
+        public void Conv_Ovf_U2_Un()
+        {
+            throw new NotImplementedException();
+        }
+        public void Conv_Ovf_I4_Un()
+        {
+            throw new NotImplementedException();
+        }
+        public void Conv_Ovf_U4_Un()
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Conv_Ovf_I8_Un()
+        {
+            throw new NotImplementedException();
+        }
+        public void Conv_Ovf_U8_Un()
+        {
+            throw new NotImplementedException();
+        }
+        public void Conv_Ovf_I_Un()
+        {
+            throw new NotImplementedException();
+        }
+        public void Conv_Ovf_U_Un()
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Ldftn(ThreadContext context, IMethod method)
+        {
+            stackCalc.Push(new RefFunc(method, null));
+            //throw new NotImplementedException();
+            _pos = _pos.Next;
+        }
+        public void Ldvirtftn(ThreadContext context, IMethod method)
+        {
+            object _this = stackCalc.Pop();
+            stackCalc.Push(new RefFunc(method, _this));
+
+            _pos = _pos.Next;
+        }
+        public void Ldarga(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Calli(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+
+
+        public void Break(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Starg_S(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldnull()
+        {
+            stackCalc.Push(null);
+            _pos = _pos.Next;
+        }
+        public void Jmp(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+
+        public void Switch(ThreadContext context, Mono.Cecil.Cil.Instruction[] poss)
+        {
+            var indexobj = stackCalc.Pop();
+            uint pos = 0;
+            if (indexobj is VBox)
+            {
+                pos = (indexobj as VBox).ToUInt();
+            }
+            else
+            {
+                pos = (uint)(int)indexobj;
+            }
+            if (pos >= poss.Length)
+            {
+                _pos = _pos.Next;
+
+            }
+            else
+            {
+                _pos = poss[pos];
+            }
+        }
+        public void Ldind_I1(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldind_U1(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldind_I2(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldind_U2(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldind_I4(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldind_U4(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldind_I8(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldind_I(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldind_R4(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldind_R8(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldind_Ref(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Stind_Ref(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Stind_I1(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Stind_I2(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Stind_I4(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Stind_I8(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Stind_R4(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Stind_R8(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void And(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Or(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Xor(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Shl(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Shr(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Shr_Un(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Not(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Cpobj(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Ldobj(ThreadContext context, object obj)
+        {
+            stackCalc.Push(obj);
+            //Type t = obj.GetType();
+            //throw new NotImplementedException();
+            _pos = _pos.Next;
+        }
+        public void Castclass(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Throw(ThreadContext context, object obj)
+        {
+            Exception exc = stackCalc.Pop() as Exception;
+            throw exc;
+            //_pos = _pos.Next;
+        }
+        public void Stobj(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Refanyval(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Mkrefany(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+
+        public void Add_Ovf(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Add_Ovf_Un(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Mul_Ovf(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Mul_Ovf_Un(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Sub_Ovf(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Sub_Ovf_Un(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Endfinally(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Stind_I(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Arglist(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+
+        public void Starg(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Localloc(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Endfilter(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Unaligned(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Volatile(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Tail(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Initobj(ThreadContext context, ICLRType _type)
+        {
+            RefObj _this = stackCalc.Pop() as RefObj;
+
+            //var typesys = context.environment.GetType(method.DeclaringType.FullName, method.Module);
+            var _object = _type.InitObj();
+
+            _this.Set(_object);
+
+            _pos = _pos.Next;
+        }
+        public void Cpblk(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Initblk(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void No(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Rethrow(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Sizeof(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Refanytype(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+        public void Readonly(ThreadContext context, object obj)
+        {
+            Type t = obj.GetType();
+            throw new NotImplementedException(t.ToString());
+            //_pos = _pos.Next;
+        }
+    }
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/Execute/StackFrame.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 5241929f3062a2e489f0ad1b06c94b65
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 1509 - 0
Unity/Assets/Plugins/CLRSharp/Execute/ValueOnStack.cs

@@ -0,0 +1,1509 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    //栈上值类型,拆箱,装箱转换非常频繁,需要处理一下。
+    //
+    public class ValueOnStack
+    {
+        static Dictionary<Type, NumberType> typecode = null;
+        public static NumberType GetTypeCode(Type type)
+        {
+            if (typecode == null)
+            {
+                typecode = new Dictionary<Type, NumberType>();
+                //typecode[null] = 0;
+                typecode[typeof(bool)] = NumberType.BOOL;
+                typecode[typeof(sbyte)] = NumberType.SBYTE;
+                typecode[typeof(byte)] = NumberType.BYTE;
+                typecode[typeof(Int16)] = NumberType.INT16;
+                typecode[typeof(UInt16)] = NumberType.UINT16;
+                typecode[typeof(Int32)] = NumberType.INT32;
+                typecode[typeof(UInt32)] = NumberType.UINT32;
+                typecode[typeof(Int64)] = NumberType.INT64;
+                typecode[typeof(UInt64)] = NumberType.UINT64;
+                typecode[typeof(float)] = NumberType.FLOAT;
+                typecode[typeof(double)] = NumberType.DOUBLE;
+                typecode[typeof(IntPtr)] = NumberType.INTPTR;
+                typecode[typeof(UIntPtr)] = NumberType.UINTPTR;
+                typecode[typeof(decimal)] = NumberType.DECIMAL;
+                typecode[typeof(char)] = NumberType.CHAR;
+
+            }
+            if (type.IsEnum) return NumberType.ENUM;
+            NumberType t = NumberType.IsNotNumber;
+            typecode.TryGetValue(type, out t);
+            return t;
+        }
+        ////valuetype
+        //        public NumberType TypeOnDef;
+        //        public NumberOnStack TypeOnStack;
+        //        public IBox box;
+        //public static IBox Make(ICLRType type)
+        //{
+        //    return Make(type.TypeForSystem);
+
+        //}
+        public static VBox MakeVBox(ICLRType type)
+        {
+            return MakeVBox(type.TypeForSystem);
+        }
+        //public static IBox MakeBool(bool b)
+        //{
+        //    BoxInt32 box = Make(NumberType.BOOL) as BoxInt32;
+        //    box.value = b ? 1 : 0;
+        //    return box;
+        //}
+        public static VBox MakeVBoxBool(bool b)
+        {
+            VBox box = MakeVBox(NumberType.BOOL);
+            box.v32 = b ? 1 : 0;
+            return box;
+        }
+        //public static IBox Make(System.Type type)
+        //{
+        //    NumberType code = GetTypeCode(type);
+        //    return Make(code);
+        //}
+        public static VBox MakeVBox(System.Type type)
+        {
+            NumberType code = GetTypeCode(type);
+            return MakeVBox(code);
+        }
+        //public static IBox Make(NumberType code)
+        //{
+
+        //    switch (code)
+        //    {
+        //        case NumberType.BOOL:
+        //        case NumberType.SBYTE:
+        //        case NumberType.BYTE:
+        //        case NumberType.CHAR:
+        //        case NumberType.INT16:
+        //        case NumberType.UINT16:
+        //        case NumberType.INT32:
+        //        case NumberType.UINT32:
+        //            if (unusedInt32.Count > 0)
+        //            {
+        //                var b = unusedInt32.Dequeue();
+        //                b.type = code;
+        //                return b;
+        //            }
+        //            else
+        //                return new BoxInt32(code);
+        //        case NumberType.INT64:
+        //        case NumberType.UINT64:
+        //            if (unusedInt64.Count > 0)
+        //            {
+        //                var b = unusedInt64.Dequeue();
+        //                b.type = code;
+        //                return b;
+        //            }
+        //            else
+        //                return new BoxInt64(code);
+        //        case NumberType.FLOAT:
+        //        case NumberType.DOUBLE:
+        //            if (unusedIntFL.Count > 0)
+        //            {
+        //                var b = unusedIntFL.Dequeue();
+        //                b.type = code;
+        //                return b;
+        //            }
+        //            else
+        //                return new BoxDouble(code);
+        //        default:
+        //            return null;
+        //    }
+
+        //}
+        public static VBox MakeVBox(NumberType code)
+        {
+
+            switch (code)
+            {
+                case NumberType.BOOL:
+                case NumberType.SBYTE:
+                case NumberType.BYTE:
+                case NumberType.CHAR:
+                case NumberType.INT16:
+                case NumberType.UINT16:
+                case NumberType.INT32:
+                case NumberType.UINT32:
+                case NumberType.ENUM:
+                    if (unusedVBox.Count > 0)
+                    {
+                        var b = unusedVBox.Dequeue();
+                        b.typeStack = NumberOnStack.Int32;
+                        b.type = code;
+                        return b;
+                    }
+                    return new VBox(NumberOnStack.Int32, code);
+                case NumberType.INT64:
+                case NumberType.UINT64:
+                    if (unusedVBox.Count > 0)
+                    {
+                        var b = unusedVBox.Dequeue();
+                        b.typeStack = NumberOnStack.Int64;
+                        b.type = code;
+                        return b;
+                    }
+                    return new VBox(NumberOnStack.Int64, code);
+                case NumberType.FLOAT:
+                case NumberType.DOUBLE:
+                    if (unusedVBox.Count > 0)
+                    {
+                        var b = unusedVBox.Dequeue();
+                        b.typeStack = NumberOnStack.Double;
+                        b.type = code;
+                        return b;
+                    }
+                    return new VBox(NumberOnStack.Double, code);
+                default:
+                    return null;
+            }
+
+        }
+        //public static IBox Convert(IBox box, NumberType type)
+        //{
+        //    switch (type)
+        //    {
+        //        case NumberType.BOOL:
+        //        case NumberType.SBYTE:
+        //        case NumberType.BYTE:
+        //        case NumberType.CHAR:
+        //        case NumberType.INT16:
+        //        case NumberType.UINT16:
+        //        case NumberType.INT32:
+        //        case NumberType.UINT32:
+        //            {
+        //                if (box is BoxInt32) return box;
+        //                BoxInt32 v32 = ValueOnStack.Make(type) as BoxInt32;
+        //                BoxInt64 b64 = box as BoxInt64;
+        //                BoxDouble bdb = box as BoxDouble;
+        //                if (b64 != null)
+        //                    v32.value = (int)b64.value;
+        //                else
+        //                    v32.value = (int)bdb.value;
+        //                return v32;
+        //            }
+        //        case NumberType.INT64:
+        //        case NumberType.UINT64:
+        //            {
+        //                if (box is BoxInt64) return box;
+        //                BoxInt64 v64 = ValueOnStack.Make(type) as BoxInt64;
+        //                BoxInt32 b32 = box as BoxInt32;
+        //                BoxDouble bdb = box as BoxDouble;
+        //                if (b32 != null)
+        //                    v64.value = b32.value;
+        //                else
+        //                    v64.value = (Int64)bdb.value;
+        //                return v64;
+        //            }
+        //        case NumberType.FLOAT:
+        //        case NumberType.DOUBLE:
+        //            {
+        //                if (box is BoxDouble) return box;
+        //                BoxDouble vdb = new BoxDouble(type);
+        //                BoxInt32 b32 = box as BoxInt32;
+        //                BoxInt64 b64 = box as BoxInt64;
+        //                if (b32 != null)
+        //                    vdb.value = b32.value;
+        //                else
+        //                    vdb.value = b64.value;
+        //                return vdb;
+        //            }
+        //        default:
+        //            return null;
+        //    }
+        //}
+
+        public static VBox Convert(VBox box, NumberType type)
+        {
+            VBox b = MakeVBox(type);
+            b.Set(box);
+            return b;
+        }
+        //public static Queue<IBox> unusedInt32 = new Queue<IBox>();
+        //public static Queue<IBox> unusedInt64 = new Queue<IBox>();
+        //public static Queue<IBox> unusedIntFL = new Queue<IBox>();
+
+        public static Queue<VBox> unusedVBox = new Queue<VBox>();
+        public static void UnUse(VBox box)
+        {
+            box.refcount = 0;
+            unusedVBox.Enqueue(box);
+        }
+        //public static void UnUse(IBox box)
+        //{
+        //    switch (box.typeStack)
+        //    {
+        //        case NumberOnStack.Int32:
+        //            unusedInt32.Enqueue(box);
+        //            break;
+        //        case NumberOnStack.Int64:
+        //            unusedInt64.Enqueue(box);
+        //            break;
+        //        case NumberOnStack.Double:
+        //            unusedIntFL.Enqueue(box);
+        //            break;
+        //    }
+        //}
+    }
+    public enum NumberType
+    {
+        IsNotNumber = 0,
+        SBYTE = 1,
+        BYTE = 2,
+        INT16 = 3,
+        UINT16 = 4,
+        INT32 = 5,
+        UINT32 = 6,
+        INT64 = 7,
+        UINT64 = 8,
+        FLOAT = 9,
+        DOUBLE = 10,
+        INTPTR = 11,
+        UINTPTR = 12,
+        DECIMAL = 13,
+        CHAR = 14,
+        BOOL = 15,
+        ENUM = 16,
+    };
+    public enum NumberOnStack
+    {
+        Int32,
+        Int64,
+        Double,
+    }
+    public class VBox
+    {
+        public VBox(NumberOnStack typeStack, NumberType thistype)
+        {
+            this.typeStack = typeStack;
+            this.type = thistype;
+        }
+        public VBox Clone()
+        {
+            VBox b = ValueOnStack.MakeVBox(this.type);
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    b.v32 = this.v32;
+                    break;
+                case NumberOnStack.Int64:
+                    b.v64 = this.v64;
+                    break;
+                case NumberOnStack.Double:
+                    b.vDF = this.v64;
+                    break;
+
+            }
+
+            return b;
+        }
+        public int refcount = 0;
+        public NumberOnStack typeStack;
+        public NumberType type;
+        public Int32 v32;
+        public Int64 v64;
+        public Double vDF;
+        public object BoxStack()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return v32;
+                case NumberOnStack.Int64:
+                    return v64;
+                case NumberOnStack.Double:
+                    return vDF;
+                default:
+                    return null;
+            }
+
+        }
+        public object BoxDefine()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    switch (type)
+                    {
+                        case NumberType.ENUM:
+                            return v32;
+                        case NumberType.BOOL:
+                            return (v32 > 0);
+                        case NumberType.SBYTE:
+                            return (sbyte)v32;
+                        case NumberType.BYTE:
+                            return (byte)v32;
+                        case NumberType.CHAR:
+                            return (char)v32;
+                        case NumberType.INT16:
+                            return (Int16)v32;
+                        case NumberType.UINT16:
+                            return (UInt16)v32;
+                        case NumberType.INT32:
+                            return (Int32)v32;
+                        case NumberType.UINT32:
+                            return (UInt32)v32;
+                        case NumberType.INT64:
+                            return (Int64)v32;
+                        case NumberType.UINT64:
+                            return (UInt64)v32;
+                        case NumberType.FLOAT:
+                            return (float)v32;
+                        case NumberType.DOUBLE:
+                            return (double)v32;
+                        default:
+                            return null;
+                    }
+                case NumberOnStack.Int64:
+                    switch (type)
+                    {
+                        case NumberType.BOOL:
+                            return (v64 > 0);
+                        case NumberType.SBYTE:
+                            return (sbyte)v64;
+                        case NumberType.BYTE:
+                            return (byte)v64;
+                        case NumberType.CHAR:
+                            return (char)v64;
+                        case NumberType.INT16:
+                            return (Int16)v64;
+                        case NumberType.UINT16:
+                            return (UInt16)v64;
+                        case NumberType.INT32:
+                            return (Int32)v64;
+                        case NumberType.UINT32:
+                            return (UInt32)v64;
+                        case NumberType.INT64:
+                            return (Int64)v64;
+                        case NumberType.UINT64:
+                            return (UInt64)v64;
+                        case NumberType.FLOAT:
+                            return (float)v64;
+                        case NumberType.DOUBLE:
+                            return (double)v64;
+                        default:
+                            return null;
+                    }
+                case NumberOnStack.Double:
+                    switch (type)
+                    {
+                        case NumberType.BOOL:
+                            return (vDF > 0);
+                        case NumberType.SBYTE:
+                            return (sbyte)vDF;
+                        case NumberType.BYTE:
+                            return (byte)vDF;
+                        case NumberType.CHAR:
+                            return (char)vDF;
+                        case NumberType.INT16:
+                            return (Int16)vDF;
+                        case NumberType.UINT16:
+                            return (UInt16)vDF;
+                        case NumberType.INT32:
+                            return (Int32)vDF;
+                        case NumberType.UINT32:
+                            return (UInt32)vDF;
+                        case NumberType.INT64:
+                            return (Int64)vDF;
+                        case NumberType.UINT64:
+                            return (UInt64)vDF;
+                        case NumberType.FLOAT:
+                            return (float)vDF;
+                        case NumberType.DOUBLE:
+                            return (double)vDF;
+                        default:
+                            return null;
+                    }
+                default:
+                    return null;
+            }
+
+        }
+
+        public void Add(VBox right)
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    v32 += right.v32;
+                    break;
+                case NumberOnStack.Int64:
+                    v64 += right.v64;
+                    break;
+                case NumberOnStack.Double:
+                    vDF += right.vDF;
+                    break;
+            }
+        }
+        public void Sub(VBox right)
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    v32 -= right.v32;
+                    break;
+                case NumberOnStack.Int64:
+                    v64 -= right.v64;
+                    break;
+                case NumberOnStack.Double:
+                    vDF -= right.vDF;
+                    break;
+            }
+        }
+        public void Mul(VBox right)
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    v32 *= right.v32;
+                    break;
+                case NumberOnStack.Int64:
+                    v64 *= right.v64;
+                    break;
+                case NumberOnStack.Double:
+                    vDF *= right.vDF;
+                    break;
+            }
+        }
+        public void Div(VBox right)
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    v32 /= right.v32;
+                    break;
+                case NumberOnStack.Int64:
+                    v64 /= right.v64;
+                    break;
+                case NumberOnStack.Double:
+                    vDF /= right.vDF;
+                    break;
+            }
+        }
+        public void Mod(VBox right)
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    v32 %= right.v32;
+                    break;
+                case NumberOnStack.Int64:
+                    v64 %= right.v64;
+                    break;
+                case NumberOnStack.Double:
+                    vDF %= right.vDF;
+                    break;
+            }
+        }
+
+        //似乎Clone可以替代New系列
+        public VBox Mod_New(VBox right)
+        {
+            VBox newbox = ValueOnStack.MakeVBox(type);
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    newbox.v32 = v32 % right.v32;
+                    break;
+                case NumberOnStack.Int64:
+                    newbox.v64 = v64 % right.v64;
+                    break;
+                case NumberOnStack.Double:
+                    newbox.vDF = vDF % right.vDF;
+                    break;
+            }
+            return newbox;
+
+        }
+
+        //SetValue
+        public void SetDirect(object value)
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    if (value is bool)
+                    {
+                        v32 = ((bool)value) ? 1 : 0;
+                    }
+                    else
+                    {
+                        v32 = (int)value;
+                    }
+                    break;
+                case NumberOnStack.Int64:
+                    v64 = (Int64)value;
+                    break;
+                case NumberOnStack.Double:
+                    vDF = (double)Convert.ToDecimal(value);
+                    break;
+            }
+        }
+        public void Set(VBox value)
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    if (value.typeStack == typeStack)
+                        v32 = value.v32;
+                    else
+                        v32 = value.ToInt();
+                    break;
+                case NumberOnStack.Int64:
+                    if (value.typeStack == typeStack)
+                        v64 = value.v64;
+                    else
+                        v64 = value.ToInt64();
+                    break;
+                case NumberOnStack.Double:
+                    if (value.typeStack == typeStack)
+                        vDF = value.vDF;
+                    else
+                        vDF = value.ToDouble();
+                    break;
+            }
+        }
+
+
+        public bool logic_eq(VBox right)//=
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return v32 == right.v32;
+                case NumberOnStack.Int64:
+                    return v64 == right.v64;
+                case NumberOnStack.Double:
+                    return vDF == right.vDF;
+                default:
+                    return false;
+            }
+        }
+        public bool logic_ne(VBox right)//!=
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return v32 != right.v32;
+                case NumberOnStack.Int64:
+                    return v64 != right.v64;
+                case NumberOnStack.Double:
+                    return vDF != right.vDF;
+                default:
+                    return false;
+            }
+        }
+        public bool logic_ne_Un(VBox right)//!=
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (uint)v32 != (uint)right.v32;
+                case NumberOnStack.Int64:
+                    return (UInt64)v64 != (UInt64)right.v64;
+                case NumberOnStack.Double:
+                    return vDF != right.vDF;
+                default:
+                    return false;
+            }
+        }
+        public bool logic_ge(VBox right)//>=
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return v32 >= right.v32;
+                case NumberOnStack.Int64:
+                    return v64 >= right.v64;
+                case NumberOnStack.Double:
+                    return vDF >= right.vDF;
+                default:
+                    return false;
+            }
+        }
+        public bool logic_ge_Un(VBox right)//>=
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (uint)v32 >= (uint)right.v32;
+                case NumberOnStack.Int64:
+                    return (UInt64)v64 >= (UInt64)right.v64;
+                case NumberOnStack.Double:
+                    return vDF >= right.vDF;
+                default:
+                    return false;
+            }
+        }
+        public bool logic_le(VBox right)//<=
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return v32 <= right.v32;
+                case NumberOnStack.Int64:
+                    return v64 <= right.v64;
+                case NumberOnStack.Double:
+                    return vDF <= right.vDF;
+                default:
+                    return false;
+            }
+        }
+        public bool logic_le_Un(VBox right)
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (uint)v32 <= (uint)right.v32;
+                case NumberOnStack.Int64:
+                    return (UInt64)v64 <= (UInt64)right.v64;
+                case NumberOnStack.Double:
+                    return vDF <= right.vDF;
+                default:
+                    return false;
+            }
+        }
+        public bool logic_gt(VBox right)//>
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return v32 > right.v32;
+                case NumberOnStack.Int64:
+                    return v64 > right.v64;
+                case NumberOnStack.Double:
+                    return vDF > right.vDF;
+                default:
+                    return false;
+            }
+        }
+        public bool logic_gt_Un(VBox right)//>
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (uint)v32 > (uint)right.v32;
+                case NumberOnStack.Int64:
+                    return (UInt64)v64 > (UInt64)right.v64;
+                case NumberOnStack.Double:
+                    return vDF > right.vDF;
+                default:
+                    return false;
+            }
+        }
+        public bool logic_lt(VBox right)//<
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return v32 < right.v32;
+                case NumberOnStack.Int64:
+                    return v64 < right.v64;
+                case NumberOnStack.Double:
+                    return vDF < right.vDF;
+                default:
+                    return false;
+            }
+        }
+        public bool logic_lt_Un(VBox right)//<
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (uint)v32 < (uint)right.v32;
+                case NumberOnStack.Int64:
+                    return (UInt64)v64 < (UInt64)right.v64;
+                case NumberOnStack.Double:
+                    return vDF < right.vDF;
+                default:
+                    return false;
+            }
+        }
+        //////////////////////
+        //To
+        public bool ToBool()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return v32 > 0;
+                case NumberOnStack.Int64:
+                    return v64 > 0;
+                default:
+                    return false;
+            }
+        }
+        public char ToChar()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (char)v32;
+                case NumberOnStack.Int64:
+                    return (char)v64;
+                case NumberOnStack.Double:
+                    return (char)vDF;
+                default:
+                    return (char)0;
+            }
+        }
+        public byte ToByte()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (byte)v32;
+                case NumberOnStack.Int64:
+                    return (byte)v64;
+                case NumberOnStack.Double:
+                    return (byte)vDF;
+                default:
+                    return 0;
+            }
+        }
+        public sbyte ToSByte()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (sbyte)v32;
+                case NumberOnStack.Int64:
+                    return (sbyte)v64;
+                case NumberOnStack.Double:
+                    return (sbyte)vDF;
+                default:
+                    return 0;
+            }
+        }
+        public Int16 ToInt16()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (Int16)v32;
+                case NumberOnStack.Int64:
+                    return (Int16)v64;
+                case NumberOnStack.Double:
+                    return (Int16)vDF;
+                default:
+                    return 0;
+            }
+        }
+        public UInt16 ToUInt16()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (UInt16)v32;
+                case NumberOnStack.Int64:
+                    return (UInt16)v64;
+                case NumberOnStack.Double:
+                    return (UInt16)vDF;
+                default:
+                    return 0;
+            }
+        }
+        public int ToInt()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (int)v32;
+                case NumberOnStack.Int64:
+                    return (int)v64;
+                case NumberOnStack.Double:
+                    return (int)vDF;
+                default:
+                    return 0;
+            }
+        }
+        public uint ToUInt()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (uint)v32;
+                case NumberOnStack.Int64:
+                    return (uint)v64;
+                case NumberOnStack.Double:
+                    return (uint)vDF;
+                default:
+                    return 0;
+            }
+        }
+        public Int64 ToInt64()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (Int64)v32;
+                case NumberOnStack.Int64:
+                    return (Int64)v64;
+                case NumberOnStack.Double:
+                    return (Int64)vDF;
+                default:
+                    return 0;
+            }
+        }
+        public UInt64 ToUInt64()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (UInt64)v32;
+                case NumberOnStack.Int64:
+                    return (UInt64)v64;
+                case NumberOnStack.Double:
+                    return (UInt64)vDF;
+                default:
+                    return 0;
+            }
+        }
+        public float ToFloat()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (float)v32;
+                case NumberOnStack.Int64:
+                    return (float)v64;
+                case NumberOnStack.Double:
+                    return (float)vDF;
+                default:
+                    return 0;
+            }
+        }
+        public double ToDouble()
+        {
+            switch (typeStack)
+            {
+                case NumberOnStack.Int32:
+                    return (double)v32;
+                case NumberOnStack.Int64:
+                    return (double)v64;
+                case NumberOnStack.Double:
+                    return (double)vDF;
+                default:
+                    return 0;
+            }
+        }
+
+
+    }
+    //public interface IBox
+    //{
+    //    object BoxStack();
+    //    object BoxDefine();
+
+    //    void Add(IBox right);
+    //    void Sub(IBox right);
+    //    void Mul(IBox right);
+    //    void Div(IBox right);
+    //    void Mod(IBox right);
+
+    //    IBox Mod_New(IBox right);
+    //    void SetDirect(object value);
+    //    void Set(IBox value);
+
+    //    NumberType type
+    //    {
+    //        get;
+    //        set;
+    //    }
+
+    //    NumberOnStack typeStack
+    //    {
+    //        get;
+    //    }
+
+    //    bool logic_eq(IBox right);//=
+    //    bool logic_ne(IBox right);//!=
+    //    bool logic_ne_Un(IBox right);//!=
+    //    bool logic_ge(IBox right);//>=
+    //    bool logic_ge_Un(IBox right);//>=
+    //    bool logic_le(IBox right);//<=
+    //    bool logic_le_Un(IBox right);
+    //    bool logic_gt(IBox right);//>
+    //    bool logic_gt_Un(IBox right);//>
+    //    bool logic_lt(IBox right);//<
+    //    bool logic_lt_Un(IBox right);//<
+
+    //    bool ToBool();
+    //    int ToInt();
+    //    uint ToUint();
+
+    //    Int64 ToInt64();
+    //    float ToFloat();
+
+    //    double ToDouble();
+
+    //    int refcount
+    //    {
+    //        get;
+    //        set;
+    //    }
+    //}
+    //public class BoxInt32 : IBox
+    //{
+    //    public int refcount
+    //    {
+    //        get;
+    //        set;
+    //    }
+    //    public BoxInt32(NumberType type)
+    //    {
+    //        this.type = type;
+    //    }
+    //    public NumberType type
+    //    {
+    //        get;
+    //        set;
+    //    }
+    //    public NumberOnStack typeStack
+    //    {
+    //        get
+    //        {
+    //            return NumberOnStack.Int32;
+    //        }
+    //    }
+    //    public Int32 value;
+    //    public object BoxStack()
+    //    {
+    //        return value;
+    //    }
+
+    //    public object BoxDefine()
+    //    {
+    //        switch (type)
+    //        {
+    //            case NumberType.BOOL:
+    //                return (value > 0);
+    //            case NumberType.SBYTE:
+    //                return (sbyte)value;
+    //            case NumberType.BYTE:
+    //                return (byte)value;
+    //            case NumberType.CHAR:
+    //                return (char)value;
+    //            case NumberType.INT16:
+    //                return (Int16)value;
+    //            case NumberType.UINT16:
+    //                return (UInt16)value;
+    //            case NumberType.INT32:
+    //                return (Int32)value;
+    //            case NumberType.UINT32:
+    //                return (UInt32)value;
+    //            case NumberType.INT64:
+    //                return (Int64)value;
+    //            case NumberType.UINT64:
+    //                return (UInt64)value;
+    //            case NumberType.FLOAT:
+    //                return (float)value;
+    //            case NumberType.DOUBLE:
+    //                return (double)value;
+    //            default:
+    //                return null;
+    //        }
+
+    //    }
+
+    //    public void Set(IBox value)
+    //    {
+
+    //        this.value = (value as BoxInt32).value;
+    //    }
+    //    public void SetDirect(object value)
+    //    {
+    //        if (value is bool)
+    //        {
+    //            this.value = (bool)value ? 1 : 0;
+    //        }
+    //        else
+    //        {
+    //            this.value = (int)value;
+    //        }
+    //    }
+    //    public void Add(IBox right)
+    //    {
+    //        this.value += (right as BoxInt32).value;
+    //    }
+
+    //    public void Sub(IBox right)
+    //    {
+    //        this.value -= (right as BoxInt32).value;
+    //    }
+
+    //    public void Mul(IBox right)
+    //    {
+    //        this.value *= (right as BoxInt32).value;
+    //    }
+
+    //    public void Div(IBox right)
+    //    {
+    //        this.value /= (right as BoxInt32).value;
+    //    }
+    //    public void Mod(IBox right)
+    //    {
+    //        this.value %= (right as BoxInt32).value;
+    //    }
+
+    //    public IBox Mod_New(IBox right)
+    //    {
+    //        BoxInt32 b = ValueOnStack.Make(this.type) as BoxInt32;
+    //        b.value = this.value % (right as BoxInt32).value;
+    //        return b;
+    //    }
+
+    //    public bool logic_eq(IBox right)
+    //    {
+    //        return value == (right as BoxInt32).value;
+    //    }
+
+
+    //    public bool logic_ne(IBox right)
+    //    {
+    //        return value != (right as BoxInt32).value;
+    //    }
+
+    //    public bool logic_ne_Un(IBox right)
+    //    {
+    //        return (UInt32)value != (UInt32)(right as BoxInt32).value;
+    //    }
+
+    //    public bool logic_ge(IBox right)
+    //    {
+    //        return value >= (right as BoxInt32).value;
+    //    }
+
+    //    public bool logic_ge_Un(IBox right)
+    //    {
+    //        return (UInt32)value >= (UInt32)(right as BoxInt32).value;
+    //    }
+
+    //    public bool logic_le(IBox right)
+    //    {
+    //        return value <= (right as BoxInt32).value;
+    //    }
+
+    //    public bool logic_le_Un(IBox right)
+    //    {
+    //        return (UInt32)value <= (UInt32)(right as BoxInt32).value;
+    //    }
+
+    //    public bool logic_gt(IBox right)
+    //    {
+    //        return value > (right as BoxInt32).value;
+    //    }
+
+    //    public bool logic_gt_Un(IBox right)
+    //    {
+    //        return (UInt32)value > (UInt32)(right as BoxInt32).value;
+    //    }
+
+    //    public bool logic_lt(IBox right)
+    //    {
+    //        return value < (right as BoxInt32).value;
+    //    }
+
+    //    public bool logic_lt_Un(IBox right)
+    //    {
+    //        return (UInt32)value < (UInt32)(right as BoxInt32).value;
+    //    }
+
+    //    public bool ToBool()
+    //    {
+    //        return value > 0;
+    //    }
+    //    public int ToInt()
+    //    {
+    //        return (int)value;
+    //    }
+    //    public uint ToUint()
+    //    {
+    //        return (uint)value;
+    //    }
+    //    public Int64 ToInt64()
+    //    {
+    //        return (Int64)value;
+    //    }
+    //    public float ToFloat()
+    //    {
+    //        return (float)value;
+    //    }
+
+    //    public double ToDouble()
+    //    {
+    //        return (double)value;
+    //    }
+    //}
+    //public class BoxInt64 : IBox
+    //{
+    //    public int refcount
+    //    {
+    //        get;
+    //        set;
+    //    }
+    //    public BoxInt64(NumberType type)
+    //    {
+    //        this.type = type;
+    //    }
+    //    public NumberType type
+    //    {
+    //        get;
+    //        set;
+    //    }
+    //    public NumberOnStack typeStack
+    //    {
+    //        get
+    //        {
+    //            return NumberOnStack.Int64;
+    //        }
+    //    }
+    //    public Int64 value;
+    //    public object BoxStack()
+    //    {
+    //        return value;
+    //    }
+
+    //    public object BoxDefine()
+    //    {
+    //        switch (type)
+    //        {
+    //            case NumberType.BOOL:
+    //                return (value > 0);
+    //            case NumberType.SBYTE:
+    //                return (sbyte)value;
+    //            case NumberType.BYTE:
+    //                return (byte)value;
+    //            case NumberType.CHAR:
+    //                return (char)value;
+    //            case NumberType.INT16:
+    //                return (Int16)value;
+    //            case NumberType.UINT16:
+    //                return (UInt16)value;
+    //            case NumberType.INT32:
+    //                return (Int32)value;
+    //            case NumberType.UINT32:
+    //                return (UInt32)value;
+    //            case NumberType.INT64:
+    //                return (Int64)value;
+    //            case NumberType.UINT64:
+    //                return (UInt64)value;
+    //            case NumberType.FLOAT:
+    //                return (float)value;
+    //            case NumberType.DOUBLE:
+    //                return (double)value;
+    //            default:
+    //                return null;
+    //        }
+
+    //    }
+    //    public void Set(IBox value)
+    //    {
+    //        this.value = (value as BoxInt64).value;
+    //    }
+    //    public void SetDirect(object value)
+    //    {
+    //        this.value = (Int64)value;
+    //    }
+    //    public void Add(IBox right)
+    //    {
+    //        this.value += (right as BoxInt64).value;
+    //    }
+
+    //    public void Sub(IBox right)
+    //    {
+    //        this.value -= (right as BoxInt64).value;
+    //    }
+
+    //    public void Mul(IBox right)
+    //    {
+    //        this.value *= (right as BoxInt64).value;
+    //    }
+
+    //    public void Div(IBox right)
+    //    {
+    //        this.value /= (right as BoxInt64).value;
+    //    }
+    //    public void Mod(IBox right)
+    //    {
+    //        this.value %= (right as BoxInt64).value;
+    //    }
+    //    public IBox Mod_New(IBox right)
+    //    {
+    //        BoxInt64 b = ValueOnStack.Make(this.type) as BoxInt64;
+    //        b.value = this.value % (right as BoxInt64).value;
+    //        return b;
+    //    }
+
+    //    public bool logic_eq(IBox right)
+    //    {
+    //        return value == (right as BoxInt64).value;
+    //    }
+
+
+    //    public bool logic_ne(IBox right)
+    //    {
+    //        return value != (right as BoxInt64).value;
+    //    }
+
+    //    public bool logic_ne_Un(IBox right)
+    //    {
+    //        return (UInt64)value != (UInt64)(right as BoxInt64).value;
+    //    }
+
+    //    public bool logic_ge(IBox right)
+    //    {
+    //        return value >= (right as BoxInt64).value;
+    //    }
+
+    //    public bool logic_ge_Un(IBox right)
+    //    {
+    //        return (UInt64)value >= (UInt64)(right as BoxInt64).value;
+    //    }
+
+    //    public bool logic_le(IBox right)
+    //    {
+    //        return value <= (right as BoxInt64).value;
+    //    }
+
+    //    public bool logic_le_Un(IBox right)
+    //    {
+    //        return (UInt64)value <= (UInt64)(right as BoxInt64).value;
+    //    }
+
+    //    public bool logic_gt(IBox right)
+    //    {
+    //        return value > (right as BoxInt64).value;
+    //    }
+
+    //    public bool logic_gt_Un(IBox right)
+    //    {
+    //        return (UInt64)value > (UInt64)(right as BoxInt64).value;
+    //    }
+
+    //    public bool logic_lt(IBox right)
+    //    {
+    //        return value < (right as BoxInt64).value;
+    //    }
+
+    //    public bool logic_lt_Un(IBox right)
+    //    {
+    //        return (UInt64)value < (UInt64)(right as BoxInt64).value;
+    //    }
+    //    public bool ToBool()
+    //    {
+    //        return value > 0;
+    //    }
+    //    public int ToInt()
+    //    {
+    //        return (int)value;
+    //    }
+    //    public uint ToUint()
+    //    {
+    //        return (uint)value;
+    //    }
+    //    public Int64 ToInt64()
+    //    {
+    //        return (Int64)value;
+    //    }
+    //    public float ToFloat()
+    //    {
+    //        return (float)value;
+    //    }
+
+    //    public double ToDouble()
+    //    {
+    //        return (double)value;
+    //    }
+    //}
+    //public class BoxDouble : IBox
+    //{
+    //    public int refcount
+    //    {
+    //        get;
+    //        set;
+    //    }
+    //    public BoxDouble(NumberType type)
+    //    {
+    //        this.type = type;
+    //    }
+    //    public NumberType type
+    //    {
+    //        get;
+    //        set;
+    //    }
+    //    public NumberOnStack typeStack
+    //    {
+    //        get
+    //        {
+    //            return NumberOnStack.Double;
+    //        }
+    //    }
+    //    public double value;
+    //    public object BoxStack()
+    //    {
+    //        return value;
+    //    }
+
+    //    public object BoxDefine()
+    //    {
+    //        switch (type)
+    //        {
+    //            case NumberType.BOOL:
+    //                return (value > 0);
+    //            case NumberType.SBYTE:
+    //                return (sbyte)value;
+    //            case NumberType.BYTE:
+    //                return (byte)value;
+    //            case NumberType.CHAR:
+    //                return (char)value;
+    //            case NumberType.INT16:
+    //                return (Int16)value;
+    //            case NumberType.UINT16:
+    //                return (UInt16)value;
+    //            case NumberType.INT32:
+    //                return (Int32)value;
+    //            case NumberType.UINT32:
+    //                return (UInt32)value;
+    //            case NumberType.INT64:
+    //                return (Int64)value;
+    //            case NumberType.UINT64:
+    //                return (UInt64)value;
+    //            case NumberType.FLOAT:
+    //                return (float)value;
+    //            case NumberType.DOUBLE:
+    //                return (double)value;
+    //            default:
+    //                return null;
+    //        }
+
+    //    }
+
+    //    public void Set(IBox value)
+    //    {
+    //        this.value = (value as BoxDouble).value;
+    //    }
+    //    public void SetDirect(object value)
+    //    {
+
+    //        this.value = (double)Convert.ToDecimal(value);
+    //    }
+    //    public void Add(IBox right)
+    //    {
+    //        this.value += (right as BoxDouble).value;
+    //    }
+
+    //    public void Sub(IBox right)
+    //    {
+    //        this.value -= (right as BoxDouble).value;
+    //    }
+
+    //    public void Mul(IBox right)
+    //    {
+    //        this.value *= (right as BoxDouble).value;
+    //    }
+
+    //    public void Div(IBox right)
+    //    {
+    //        this.value /= (right as BoxDouble).value;
+    //    }
+    //    public void Mod(IBox right)
+    //    {
+    //        this.value %= (right as BoxDouble).value;
+    //    }
+
+    //    public IBox Mod_New(IBox right)
+    //    {
+    //        BoxDouble b = new BoxDouble(this.type);
+    //        b.value = this.value % (right as BoxDouble).value;
+    //        return b;
+    //    }
+
+    //    public bool logic_eq(IBox right)
+    //    {
+    //        return value == (right as BoxDouble).value;
+    //    }
+
+    //    public bool logic_ne(IBox right)
+    //    {
+    //        return value != (right as BoxDouble).value;
+    //    }
+
+    //    public bool logic_ne_Un(IBox right)
+    //    {
+    //        return value != (right as BoxDouble).value;
+    //    }
+
+    //    public bool logic_ge(IBox right)
+    //    {
+    //        return value >= (right as BoxDouble).value;
+    //    }
+
+    //    public bool logic_ge_Un(IBox right)
+    //    {
+    //        return value >= (right as BoxDouble).value;
+    //    }
+
+    //    public bool logic_le(IBox right)
+    //    {
+    //        return value <= (right as BoxDouble).value;
+    //    }
+
+    //    public bool logic_le_Un(IBox right)
+    //    {
+    //        return value <= (right as BoxDouble).value;
+    //    }
+
+    //    public bool logic_gt(IBox right)
+    //    {
+    //        return value > (right as BoxDouble).value;
+    //    }
+
+    //    public bool logic_gt_Un(IBox right)
+    //    {
+    //        return value > (right as BoxDouble).value;
+    //    }
+
+    //    public bool logic_lt(IBox right)
+    //    {
+    //        return value < (right as BoxDouble).value;
+    //    }
+
+    //    public bool logic_lt_Un(IBox right)
+    //    {
+    //        return value < (right as BoxDouble).value;
+    //    }
+    //    public bool ToBool()
+    //    {
+    //        throw new NotImplementedException();
+    //    }
+    //    public int ToInt()
+    //    {
+    //        return (int)value;
+    //    }
+    //    public uint ToUint()
+    //    {
+    //        return (uint)value;
+    //    }
+    //    public Int64 ToInt64()
+    //    {
+    //        return (Int64)value;
+    //    }
+    //    public float ToFloat()
+    //    {
+    //        return (float)value;
+    //    }
+
+    //    public double ToDouble()
+    //    {
+    //        return (double)value;
+    //    }
+    //}
+
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/Execute/ValueOnStack.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bf8480ca798060c47b525f46f4e04b13
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/CLRSharp/Interface.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: c5405d6238436f044a9f5f24c288d548
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 50 - 0
Unity/Assets/Plugins/CLRSharp/Interface/EnvAndLog.cs

@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    public interface ICLRSharp_Logger
+    {
+        void Log(string str);
+        void Log_Warning(string str);
+        void Log_Error(string str);
+    }
+    public interface ICLRSharp_Environment
+    {
+        string version
+        {
+            get;
+        }
+        void LoadModule(System.IO.Stream dllStream);
+
+        void LoadModule(System.IO.Stream dllStream, System.IO.Stream pdbStream, Mono.Cecil.Cil.ISymbolReaderProvider debugInfoLoader);
+
+        ////仅仅加载模块的名字和他引用的模块名字
+        //void LoadModule_OnlyName(System.IO.Stream dllStream);
+
+        void AddSerachAssembly(System.Reflection.Assembly assembly);
+        string[] GetAllTypes();
+        ICLRType GetType(string name);
+
+        string[] GetModuleRefNames();
+        ICLRType GetType(System.Type systemType);
+
+        void RegType(ICLRType type);
+        ICLRSharp_Logger logger
+        {
+            get;
+        }
+
+        void RegCrossBind(ICrossBind bind);
+
+        ICrossBind GetCrossBind(Type type);
+
+    }
+    public interface ICrossBind
+    {
+        Type Type
+        { get; }
+        object CreateBind(CLRSharp_Instance inst);
+    }
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/Interface/EnvAndLog.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 87e482e4f83ce3344893b345aa17e533
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/CLRSharp/Type.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: bc8d44c195b6e364e80bfd4c9f67f1f8
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/CLRSharp/Type/CLRSharp.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: 065ecdaed08ce604e914f1ab76b84251
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 39 - 0
Unity/Assets/Plugins/CLRSharp/Type/CLRSharp/CLRSharp_Instance.cs

@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    public class CLRSharp_Instance
+    {
+        public ICLRType_Sharp type
+        {
+            get;
+            private set;
+        }
+        public CLRSharp_Instance(ICLRType_Sharp type)
+        {
+            this.type = type;
+        }
+        public object system_base;
+        public Dictionary<string, object> Fields = new Dictionary<string, object>();
+
+        //每个方法都可以产生一个代理
+        public Dictionary<IMethod, Delegate> Delegates = new Dictionary<IMethod, Delegate>();
+
+        public Delegate GetDelegate(ThreadContext context, Type deleType, IMethod method)
+        {
+            Delegate dele = null;
+            if (!Delegates.TryGetValue(method, out dele))
+            {
+                dele = Delegate_Binder.MakeDelegate(deleType,  this, method);
+                Delegates[method] = dele;
+                //需要从Delegate转换成实际类型赋值的帮助类
+
+
+            }
+            return dele;
+        }
+    }
+
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/Type/CLRSharp/CLRSharp_Instance.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3b1b1890eba3f7c4ea8e6112b53eaba9
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 439 - 0
Unity/Assets/Plugins/CLRSharp/Type/CLRSharp/CLRSharp_Type.cs

@@ -0,0 +1,439 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    public class Type_Common_CLRSharp : ICLRType_Sharp
+    {
+        public System.Type TypeForSystem
+        {
+            get
+            {
+                return typeof(CLRSharp_Instance);
+            }
+        }
+        public Mono.Cecil.TypeDefinition type_CLRSharp
+        {
+            get;
+            private set;
+        }
+        public ICLRSharp_Environment env
+        {
+            get;
+            private set;
+        }
+        public ICLRType[] SubTypes
+        {
+            get;
+            private set;
+        }
+        public ICLRType BaseType
+        {
+            get;
+            private set;
+        }
+        public List<ICLRType> _Interfaces = null;
+
+        public bool ContainBase(Type t)
+        {
+            if (BaseType != null && BaseType.TypeForSystem == t) return true;
+            if (_Interfaces == null) return false;
+            foreach (var i in _Interfaces)
+            {
+                if (i.TypeForSystem == t) return true;
+            }
+            return false;
+        }
+        public bool HasSysBase
+        {
+            get;
+            private set;
+        }
+        public string[] GetMethodNames()
+        {
+            string[] t = new string[type_CLRSharp.Methods.Count];
+            for (int i = 0; i < type_CLRSharp.Methods.Count; i++)
+            {
+                t[i] = type_CLRSharp.Methods[i].Name;
+            }
+            return t;
+        }
+        public Type_Common_CLRSharp(ICLRSharp_Environment env, Mono.Cecil.TypeDefinition type)
+        {
+            this.env = env;
+            this.type_CLRSharp = type;
+            if (type_CLRSharp.BaseType != null)
+            {
+                BaseType = env.GetType(type_CLRSharp.BaseType.FullName);
+                if (BaseType is ICLRType_System)
+                {
+                    if (BaseType.TypeForSystem == typeof(object))
+                    {//都是这样,无所谓
+                        BaseType = null;
+                    }
+                    else
+                    {//继承了其他系统类型
+                        env.logger.Log("ScriptType:" + Name + " Based On a SystemType:" + BaseType.Name);
+                        HasSysBase = true;
+                    }
+                }
+                if (type_CLRSharp.HasInterfaces)
+                {
+                    _Interfaces = new List<ICLRType>();
+                    foreach (var i in type_CLRSharp.Interfaces)
+                    {
+                        var itype = env.GetType(i.FullName);
+                        if (itype is ICLRType_System)
+                        {
+                            //继承了其他系统类型
+                            env.logger.Log("ScriptType:" + Name + " Based On a SystemType:" + itype.Name);
+                            HasSysBase = true;
+                        }
+                        _Interfaces.Add(itype);
+                    }
+                }
+            }
+            foreach (var m in this.type_CLRSharp.Methods)
+            {
+                if (m.Name == ".cctor")
+                {
+                    NeedCCtor = true;
+                    break;
+                }
+            }
+
+        }
+        public IMethod GetVMethod(IMethod _base)
+        {
+            IMethod _method = null;
+            ICLRType_Sharp type = this;
+            while (type != _base.DeclaringType && type != null)
+            {
+                _method = type.GetMethod(_base.Name, _base.ParamList);
+                if (_method != null)
+                    return _method;
+                type = env.GetType(type.type_CLRSharp.BaseType.FullName) as ICLRType_Sharp;
+            }
+            return _base;
+
+        }
+        public void ResetStaticInstace()
+        {
+            this._staticInstance = null;
+            foreach (var m in this.type_CLRSharp.Methods)
+            {
+                if (m.Name == ".cctor")
+                {
+                    NeedCCtor = true;
+                    break;
+                }
+            }
+
+        }
+        public string Name
+        {
+            get { return type_CLRSharp.Name; }
+        }
+
+        public string FullName
+        {
+            get { return type_CLRSharp.FullName; }
+        }
+        public string FullNameWithAssembly
+        {
+            get
+            {
+                return type_CLRSharp.FullName;// +"," + type_CLRSharp.Module.Name;
+            }
+        }
+        public IMethod GetMethod(string funcname, MethodParamList types)
+        {
+            if (type_CLRSharp.HasMethods)
+            {
+                foreach (var m in type_CLRSharp.Methods)
+                {
+                    if (m.Name != funcname) continue;
+                    if ((types == null) ? !m.HasParameters : (m.Parameters.Count == types.Count))
+                    {
+                        bool match = true;
+                        for (int i = 0; i < ((types == null) ? 0 : types.Count); i++)
+                        {
+                            if (env.GetType(m.Parameters[i].ParameterType.FullName) != types[i])
+                            {
+                                match = false;
+                                break;
+                            }
+                        }
+                        if (match)
+                            return new Method_Common_CLRSharp(this, m);
+                    }
+                }
+            }
+            return null;
+        }
+        public object InitObj()
+        {
+            return new CLRSharp_Instance(this);
+        }
+        public IMethod GetMethodT(string funcname, MethodParamList ttypes, MethodParamList types)
+        {
+            return null;
+        }
+        public IField GetField(string name)
+        {
+            foreach (var f in type_CLRSharp.Fields)
+            {
+                if (f.Name == name)
+                {
+                    return new Field_Common_CLRSharp(this, f);
+                }
+            }
+            return null;
+        }
+        public bool IsInst(object obj)
+        {
+            if (obj is CLRSharp_Instance)
+            {
+                CLRSharp_Instance ins = obj as CLRSharp_Instance;
+                if (ins.type == this)
+                {
+                    return true;
+                }
+                //这里还要实现继承关系
+            }
+            return false;
+
+        }
+
+        public ICLRType GetNestType(ICLRSharp_Environment env, string fullname)
+        {
+            foreach (var stype in type_CLRSharp.NestedTypes)
+            {
+                if (stype.Name == fullname)
+                {
+                    var itype = new Type_Common_CLRSharp(env, stype);
+                    env.RegType(itype);
+                    return itype;
+                }
+            }
+            return null;
+        }
+
+        CLRSharp_Instance _staticInstance = null;
+        public CLRSharp_Instance staticInstance
+        {
+            get
+            {
+                if (_staticInstance == null)
+                    _staticInstance = new CLRSharp_Instance(this);
+                return _staticInstance;
+            }
+        }
+
+        public bool NeedCCtor
+        {
+            get;
+            private set;
+        }
+        public void InvokeCCtor(ThreadContext context)
+        {
+            NeedCCtor = false;
+            this.GetMethod(".cctor", null).Invoke(context, this.staticInstance, new object[] { });
+
+        }
+
+
+        public string[] GetFieldNames()
+        {
+            string[] abc = new string[type_CLRSharp.Fields.Count];
+            for (int i = 0; i < type_CLRSharp.Fields.Count; i++)
+            {
+                abc[i] = type_CLRSharp.Fields[i].Name;
+            }
+            return abc;
+        }
+    }
+    public class Method_Common_CLRSharp : IMethod_Sharp
+    {
+        Type_Common_CLRSharp _DeclaringType;
+
+        public Method_Common_CLRSharp(Type_Common_CLRSharp type, Mono.Cecil.MethodDefinition method)
+        {
+
+            if (method == null)
+                throw new Exception("not allow null method.");
+            this._DeclaringType = type;
+
+            method_CLRSharp = method;
+            ReturnType = type.env.GetType(method.ReturnType.FullName);
+
+            ParamList = new MethodParamList(type.env, method);
+        }
+        public string Name
+        {
+            get
+            {
+                return method_CLRSharp.Name;
+
+            }
+        }
+
+        public bool isStatic
+        {
+            get
+            {
+                return method_CLRSharp.IsStatic;
+            }
+        }
+        public ICLRType DeclaringType
+        {
+            get
+            {
+                return _DeclaringType;
+            }
+        }
+        public ICLRType ReturnType
+        {
+            get;
+            private set;
+
+
+        }
+        public MethodParamList ParamList
+        {
+            get;
+            private set;
+        }
+        public Mono.Cecil.MethodDefinition method_CLRSharp;
+        public object Invoke(ThreadContext context, object _this, object[] _params, bool bVisual)
+        {
+            if (context == null)
+                context = ThreadContext.activeContext;
+            if (context == null)
+                throw new Exception("这个线程上没有CLRSharp:ThreadContext");
+            if (bVisual && method_CLRSharp.IsVirtual)
+            {
+                CLRSharp_Instance inst = _this as CLRSharp_Instance;
+                if (inst.type != this.DeclaringType)
+                {
+                    IMethod impl = inst.type.GetVMethod(this);// .GetMethod(this.Name, this.ParamList);
+                    if (impl != this)
+                    {
+                        return impl.Invoke(context, _this, _params);
+                    }
+                }
+            }
+            if (method_CLRSharp.Name == ".ctor")
+            {
+                CLRSharp_Instance inst = _this as CLRSharp_Instance;
+                if (inst == null)
+                    inst = new CLRSharp_Instance(_DeclaringType);
+
+                //if (_DeclaringType.BaseType is ICLRType_System)
+                context.ExecuteFunc(this, inst, _params);
+                return inst;
+            }
+            return context.ExecuteFunc(this, _this, _params);
+        }
+        public object Invoke(ThreadContext context, object _this, object[] _params)
+        {
+            return Invoke(context, _this, _params, true);
+        }
+        public object Invoke(ThreadContext context, object _this, object[] _params, bool bVisual, bool autoLogDump)
+        {
+            try
+            {
+                return Invoke(context, _this, _params, bVisual);
+            }
+            catch (Exception err)
+            {
+                if (context == null) context = ThreadContext.activeContext;
+                if (context == null)
+                    throw new Exception("当前线程没有创建ThreadContext,无法Dump", err);
+                else
+                {
+                    context.environment.logger.Log_Error(context.Dump());
+                    throw err;
+                }
+            }
+        }
+
+        CodeBody _body = null;
+        public CodeBody body
+        {
+            get
+            {
+                if (_body == null)
+                {
+                    if (!method_CLRSharp.HasBody)
+                        return null;
+                    _body = (this.DeclaringType.env as CLRSharp_Environment).CreateCodeBody(this);
+                }
+                return _body;
+            }
+
+        }
+    }
+
+    public class Field_Common_CLRSharp : IField
+    {
+        public Type_Common_CLRSharp _DeclaringType;
+        public Mono.Cecil.FieldDefinition field;
+        public Field_Common_CLRSharp(Type_Common_CLRSharp type, Mono.Cecil.FieldDefinition field)
+        {
+            this.field = field;
+            this.FieldType = type.env.GetType(field.FieldType.FullName);
+            this._DeclaringType = type;
+
+        }
+        public ICLRType FieldType
+        {
+            get;
+            private set;
+        }
+        public ICLRType DeclaringType
+        {
+            get
+            {
+                return _DeclaringType;
+            }
+        }
+        public void Set(object _this, object value)
+        {
+            CLRSharp_Instance sins = null;
+            if (_this == null)
+            {
+                sins = _DeclaringType.staticInstance;
+            }
+            else
+            {
+                sins = _this as CLRSharp_Instance;
+            }
+
+
+            sins.Fields[field.Name] = value;
+        }
+
+        public object Get(object _this)
+        {
+            CLRSharp_Instance sins = null;
+            if (_this == null)
+            {
+                sins = _DeclaringType.staticInstance;
+            }
+            else
+            {
+                sins = _this as CLRSharp_Instance;
+            }
+            object v = null;
+            sins.Fields.TryGetValue(field.Name, out v);
+            return v;
+        }
+
+        public bool isStatic
+        {
+            get { return this.field.IsStatic; }
+        }
+    }
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/Type/CLRSharp/CLRSharp_Type.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c578631288337e84cb7020b5f5a28600
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/CLRSharp/Type/Delegate.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: 247bd17dd02a9854b9edaccfe13f1e64
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 224 - 0
Unity/Assets/Plugins/CLRSharp/Type/Delegate/Delegate_Helper.cs

@@ -0,0 +1,224 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    /// <summary>
+    /// 委托绑定
+    /// </summary>
+    public class Delegate_Binder
+    {
+        static Dictionary<Type, IDelegate_BindTool> mapBind = new Dictionary<Type, IDelegate_BindTool>();
+        public static void RegBind(Type deletype, IDelegate_BindTool bindtool)
+        {
+            mapBind[deletype] = bindtool;
+        }
+        public static Delegate MakeDelegate(Type deletype, CLRSharp_Instance __this, IMethod __method)
+        {
+            IDelegate_BindTool btool = null;
+            if (mapBind.TryGetValue(deletype, out btool))
+            {
+                return btool.CreateDele(deletype, null, __this, __method);
+            }
+            var method = deletype.GetMethod("Invoke");
+            if (__method.isStatic)
+            {
+                __this = null;
+            }
+            var pp = method.GetParameters();
+
+            if (method.ReturnType == typeof(void))
+            {
+                if (pp.Length == 0)
+                {
+                    //var gtype = typeof(Delegate_BindTool).MakeGenericType(new Type[] { });
+                    btool = new Delegate_BindTool();
+                }
+                else if (pp.Length == 1)
+                {
+                    var gtype = typeof(Delegate_BindTool<>).MakeGenericType(new Type[] { pp[0].ParameterType });
+                    btool = gtype.GetConstructor(new Type[] { }).Invoke(new object[] { }) as IDelegate_BindTool;
+                }
+                else if (pp.Length == 2)
+                {
+                    var gtype = typeof(Delegate_BindTool<,>).MakeGenericType(new Type[] { pp[0].ParameterType, pp[1].ParameterType });
+                    btool = gtype.GetConstructor(new Type[] { }).Invoke(new object[] { }) as IDelegate_BindTool;
+                }
+                else if (pp.Length == 3)
+                {
+                    var gtype = typeof(Delegate_BindTool<,,>).MakeGenericType(new Type[] { pp[0].ParameterType, pp[1].ParameterType, pp[2].ParameterType });
+                    btool = gtype.GetConstructor(new Type[] { }).Invoke(new object[] { }) as IDelegate_BindTool;
+                }
+                else if (pp.Length == 4)
+                {
+                    var gtype = typeof(Delegate_BindTool<,,,>).MakeGenericType(new Type[] { pp[0].ParameterType, pp[1].ParameterType, pp[2].ParameterType, pp[3].ParameterType });
+                    btool = gtype.GetConstructor(new Type[] { }).Invoke(new object[] { }) as IDelegate_BindTool;
+                }
+                else
+                {
+                    throw new Exception("还没有支持这么多参数的委托");
+                }
+            }
+            else
+            {
+                if (pp.Length == 0)
+                {
+                    var gtype = typeof(Delegate_BindTool_Ret<>).MakeGenericType(new Type[] { method.ReturnType });
+                    btool = gtype.GetConstructor(new Type[] { }).Invoke(new object[] { }) as IDelegate_BindTool;
+
+                }
+                else if (pp.Length == 1)
+                {
+                    var gtype = typeof(Delegate_BindTool_Ret<,>).MakeGenericType(new Type[] { method.ReturnType, pp[0].ParameterType });
+                    btool = gtype.GetConstructor(new Type[] { }).Invoke(new object[] { }) as IDelegate_BindTool;
+                }
+                else if (pp.Length == 2)
+                {
+                    var gtype = typeof(Delegate_BindTool_Ret<,,>).MakeGenericType(new Type[] { method.ReturnType, pp[0].ParameterType, pp[1].ParameterType });
+                    btool = gtype.GetConstructor(new Type[] { }).Invoke(new object[] { }) as IDelegate_BindTool;
+                }
+                else if (pp.Length == 3)
+                {
+                    var gtype = typeof(Delegate_BindTool_Ret<,,,>).MakeGenericType(new Type[] { method.ReturnType, pp[0].ParameterType, pp[1].ParameterType, pp[2].ParameterType });
+                    btool = gtype.GetConstructor(new Type[] { }).Invoke(new object[] { }) as IDelegate_BindTool;
+                }
+                else if (pp.Length == 4)
+                {
+                    var gtype = typeof(Delegate_BindTool_Ret<,,,>).MakeGenericType(new Type[] { method.ReturnType, pp[0].ParameterType, pp[1].ParameterType, pp[2].ParameterType, pp[3].ParameterType });
+                    btool = gtype.GetConstructor(new Type[] { }).Invoke(new object[] { }) as IDelegate_BindTool;
+                }
+                else
+                {
+                    throw new Exception("还没有支持这么多参数的委托");
+                }
+            }
+            mapBind[deletype] = btool;
+            return btool.CreateDele(deletype, null, __this, __method);
+        }
+    }
+    public interface IDelegate_BindTool
+    {
+        Delegate CreateDele(Type deletype, ThreadContext context, CLRSharp_Instance _this, IMethod _method);
+    }
+    public class Delegate_BindTool : IDelegate_BindTool
+    {
+        delegate void Action();
+        public Delegate CreateDele(Type deletype, ThreadContext context, CLRSharp_Instance _this, IMethod _method)
+        {
+            Action act = () =>
+            {
+                _method.Invoke(context, _this, new object[] { }, true, true);
+            };
+            return Delegate.CreateDelegate(deletype, act.Target, act.Method);
+        }
+    }
+    public class Delegate_BindTool<T1> : IDelegate_BindTool
+    {
+        delegate void Action(T1 p1);
+        public Delegate CreateDele(Type deletype, ThreadContext context, CLRSharp_Instance _this, IMethod _method)
+        {
+            Action act = (p1) =>
+            {
+                _method.Invoke(context, _this, new object[] { p1 }, true, true);
+            };
+            return Delegate.CreateDelegate(deletype, act.Target, act.Method);
+        }
+    }
+    public class Delegate_BindTool<T1, T2> : IDelegate_BindTool
+    {
+        delegate void Action(T1 p1, T2 p2);
+        public Delegate CreateDele(Type deletype, ThreadContext context, CLRSharp_Instance _this, IMethod _method)
+        {
+            Action act = (p1, p2) =>
+            {
+                _method.Invoke(context, _this, new object[] { p1, p2 }, true, true);
+            };
+            return Delegate.CreateDelegate(deletype, act.Target, act.Method);
+        }
+    }
+    public class Delegate_BindTool<T1, T2, T3> : IDelegate_BindTool
+    {
+        delegate void Action(T1 p1, T2 p2, T3 p3);
+        public Delegate CreateDele(Type deletype, ThreadContext context, CLRSharp_Instance _this, IMethod _method)
+        {
+            Action act = (p1, p2, p3) =>
+            {
+                _method.Invoke(context, _this, new object[] { p1, p2, p3 }, true, true);
+            };
+            return Delegate.CreateDelegate(deletype, act.Target, act.Method);
+        }
+    }
+    public class Delegate_BindTool<T1, T2, T3, T4> : IDelegate_BindTool
+    {
+        delegate void Action(T1 p1, T2 p2, T3 p3, T4 p4);
+        public Delegate CreateDele(Type deletype, ThreadContext context, CLRSharp_Instance _this, IMethod _method)
+        {
+            Action act = (p1, p2, p3, p4) =>
+            {
+                _method.Invoke(context, _this, new object[] { p1, p2, p3, p4 }, true, true);
+            };
+            return Delegate.CreateDelegate(deletype, act.Target, act.Method);
+        }
+    }
+    public class Delegate_BindTool_Ret<TRet> : IDelegate_BindTool
+    {
+        delegate TRet Action();
+        public Delegate CreateDele(Type deletype, ThreadContext context, CLRSharp_Instance _this, IMethod _method)
+        {
+            Action act = () =>
+            {
+                return (TRet)_method.Invoke(context, _this, new object[] { }, true, true);
+            };
+            return Delegate.CreateDelegate(deletype, act.Target, act.Method);
+        }
+    }
+    public class Delegate_BindTool_Ret<TRet, T1> : IDelegate_BindTool
+    {
+        delegate TRet Action(T1 p1);
+        public Delegate CreateDele(Type deletype, ThreadContext context, CLRSharp_Instance _this, IMethod _method)
+        {
+            Action act = (T1 p1) =>
+            {
+                return (TRet)_method.Invoke(context, _this, new object[] { p1 }, true, true);
+            };
+            return Delegate.CreateDelegate(deletype, act.Target, act.Method);
+        }
+    }
+    public class Delegate_BindTool_Ret<TRet, T1, T2> : IDelegate_BindTool
+    {
+        delegate TRet Action(T1 p1, T2 p2);
+        public Delegate CreateDele(Type deletype, ThreadContext context, CLRSharp_Instance _this, IMethod _method)
+        {
+            Action act = (T1 p1, T2 p2) =>
+            {
+                return (TRet)_method.Invoke(context, _this, new object[] { p1, p2 }, true, true);
+            };
+            return Delegate.CreateDelegate(deletype, act.Target, act.Method);
+        }
+    }
+    public class Delegate_BindTool_Ret<TRet, T1, T2, T3> : IDelegate_BindTool
+    {
+        delegate TRet Action(T1 p1, T2 p2, T3 p3);
+        public Delegate CreateDele(Type deletype, ThreadContext context, CLRSharp_Instance _this, IMethod _method)
+        {
+            Action act = (T1 p1, T2 p2, T3 p3) =>
+            {
+                return (TRet)_method.Invoke(context, _this, new object[] { p1, p2, p3 }, true, true);
+            };
+            return Delegate.CreateDelegate(deletype, act.Target, act.Method);
+        }
+    }
+    public class Delegate_BindTool_Ret<TRet, T1, T2, T3, T4> : IDelegate_BindTool
+    {
+        delegate TRet Action(T1 p1, T2 p2, T3 p3, T4 p4);
+        public Delegate CreateDele(Type deletype, ThreadContext context, CLRSharp_Instance _this, IMethod _method)
+        {
+            Action act = (T1 p1, T2 p2, T3 p3, T4 p4) =>
+            {
+                return (TRet)_method.Invoke(context, _this, new object[] { p1, p2, p3, p4 }, true, true);
+            };
+            return Delegate.CreateDelegate(deletype, act.Target, act.Method);
+        }
+    }
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/Type/Delegate/Delegate_Helper.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: df6eb1afd3e74f448921195a991c6e9d
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/CLRSharp/Type/System.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: 3ccbe4af561f45d48b1558a50f7ba9ee
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 336 - 0
Unity/Assets/Plugins/CLRSharp/Type/System/System_Type.cs

@@ -0,0 +1,336 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    class Type_Common_System : ICLRType_System
+    {
+        public System.Type TypeForSystem
+        {
+            get;
+            private set;
+        }
+        public ICLRSharp_Environment env
+        {
+            get;
+            private set;
+        }
+        public ICLRType[] SubTypes
+        {
+            get;
+            private set;
+        }
+        public Type_Common_System(ICLRSharp_Environment env, System.Type type, ICLRType[] subtype)
+        {
+            this.env = env;
+            this.TypeForSystem = type;
+            FullNameWithAssembly = type.AssemblyQualifiedName;
+            this.SubTypes = subtype;
+        }
+        public string Name
+        {
+            get { return TypeForSystem.Name; }
+        }
+
+        public string FullName
+        {
+            get { return TypeForSystem.FullName; }
+        }
+        public string FullNameWithAssembly
+        {
+            get;
+            private set;
+
+            //{
+            //    string aname = TypeForSystem.AssemblyQualifiedName;
+            //    int i = aname.IndexOf(',');
+            //    i = aname.IndexOf(',', i + 1);
+            //    return aname.Substring(0, i);
+            //}
+        }
+        public IMethod GetMethod(string funcname, MethodParamList types)
+        {
+            if (funcname == ".ctor")
+            {
+                var con = TypeForSystem.GetConstructor(types.ToArraySystem());
+                return new Method_Common_System(this, con);
+            }
+            var method = TypeForSystem.GetMethod(funcname, types.ToArraySystem());
+            return new Method_Common_System(this, method);
+        }
+        public object InitObj()
+        {
+            return Activator.CreateInstance(TypeForSystem);
+        }
+        public IMethod GetMethodT(string funcname, MethodParamList ttypes, MethodParamList types)
+        {
+            //这个实现还不完全
+            //有个别重构下,判定比这个要复杂
+            System.Reflection.MethodInfo _method = null;
+            var ms = TypeForSystem.GetMethods();
+            foreach (var m in ms)
+            {
+                if (m.Name == funcname && m.IsGenericMethodDefinition)
+                {
+                    var ts = m.GetGenericArguments();
+                    var ps = m.GetParameters();
+                    if (ts.Length == ttypes.Count && ps.Length == types.Count)
+                    {
+                        _method = m;
+                        break;
+                    }
+
+                }
+            }
+
+            // _method = TypeForSystem.GetMethod(funcname, types.ToArraySystem());
+
+            return new Method_Common_System(this, _method.MakeGenericMethod(ttypes.ToArraySystem()));
+        }
+        public IField GetField(string name)
+        {
+            return new Field_Common_System(env, TypeForSystem.GetField(name));
+        }
+        public bool IsInst(object obj)
+        {
+            return TypeForSystem.IsInstanceOfType(obj);
+
+        }
+
+
+        public ICLRType GetNestType(ICLRSharp_Environment env, string fullname)
+        {
+            throw new NotImplementedException();
+        }
+
+        public Delegate CreateDelegate(Type deletype, object _this, IMethod_System _method)
+        {
+            return Delegate.CreateDelegate(deletype, _this, _method.method_System as System.Reflection.MethodInfo);
+        }
+
+
+        public string[] GetFieldNames()
+        {
+            var fs = TypeForSystem.GetFields();
+            string[] names = new string[fs.Length];
+            for (int i = 0; i < fs.Length; i++)
+            {
+                names[i] = fs[i].Name;
+            }
+            return names;
+        }
+    }
+    class Field_Common_System : IField
+    {
+        public System.Reflection.FieldInfo info;
+        public Field_Common_System(ICLRSharp_Environment env, System.Reflection.FieldInfo field)
+        {
+            info = field;
+
+            FieldType = env.GetType(field.FieldType);
+            DeclaringType = env.GetType(field.DeclaringType);
+        }
+        public ICLRType FieldType
+        {
+            get;
+            private set;
+        }
+        public ICLRType DeclaringType
+        {
+            get;
+            private set;
+        }
+        public void Set(object _this, object value)
+        {
+            info.SetValue(_this, value);
+        }
+
+        public object Get(object _this)
+        {
+            return info.GetValue(_this);
+        }
+
+        public bool isStatic
+        {
+            get { return info.IsStatic; }
+        }
+    }
+
+    class Method_Common_System : IMethod_System
+    {
+
+        public Method_Common_System(ICLRType DeclaringType, System.Reflection.MethodBase method)
+        {
+            if (method == null)
+                throw new Exception("not allow null method.");
+            method_System = method;
+            this.DeclaringType = DeclaringType;
+            if (method is System.Reflection.MethodInfo)
+            {
+                System.Reflection.MethodInfo info = method as System.Reflection.MethodInfo;
+                ReturnType = DeclaringType.env.GetType(info.ReturnType);
+            }
+            ParamList = new MethodParamList(DeclaringType.env, method);
+        }
+        public bool isStatic
+        {
+            get { return method_System.IsStatic; }
+        }
+        public string Name
+        {
+            get
+            {
+                return method_System.Name;
+            }
+        }
+
+        public ICLRType DeclaringType
+        {
+            get;
+            private set;
+
+        }
+        public ICLRType ReturnType
+        {
+            get;
+            private set;
+        }
+        public MethodParamList ParamList
+        {
+            get;
+            private set;
+        }
+        public System.Reflection.MethodBase method_System
+        {
+            get;
+            private set;
+        }
+        public object Invoke(ThreadContext context, object _this, object[] _params, bool bVisual)
+        {//对程序类型,其实我们做不到区分虚实调用。。。没办法
+            return Invoke(context, _this, _params);
+        }
+        public object Invoke(ThreadContext context, object _this, object[] _params)
+        {
+            if (_this is CLRSharp_Instance)
+            {
+                CLRSharp_Instance inst = _this as CLRSharp_Instance;
+                if (inst.type.HasSysBase)
+                {
+                    var btype = inst.type.ContainBase(method_System.DeclaringType);
+                    if (btype)
+                    {
+                        var CrossBind = context.environment.GetCrossBind(method_System.DeclaringType);
+                        if (CrossBind != null)
+                        {
+                            _this = CrossBind.CreateBind(inst);
+                        }
+                        else
+                        {
+                            _this = (_this as CLRSharp_Instance).system_base;
+                            //如果没有绑定器,尝试直接使用System_base;
+                        }
+                        //context.environment.logger.Log("这里有一个需要映射的类型");
+                    }
+                }
+            }
+            //委托是很特殊的存在
+            //if(this.DeclaringType.IsDelegate)
+            //{
+
+            //}
+            if (method_System is System.Reflection.ConstructorInfo)
+            {
+                if (method_System.DeclaringType.IsSubclassOf(typeof(Delegate)))
+                {//创建委托
+                    object src = _params[0];
+                    RefFunc fun = _params[1] as RefFunc;
+                    ICLRType_Sharp clrtype = fun._method.DeclaringType as ICLRType_Sharp;
+                    if (clrtype != null)//onclr
+                    {
+
+                        CLRSharp_Instance inst = src as CLRSharp_Instance;
+                        if (fun._method.isStatic && clrtype != null)
+                            inst = clrtype.staticInstance;
+                        return inst.GetDelegate(context, method_System.DeclaringType, fun._method);
+                    }
+                    else//onsystem
+                    {
+                        ICLRType_System stype = fun._method.DeclaringType as ICLRType_System;
+                        return stype.CreateDelegate(method_System.DeclaringType, src, fun._method as IMethod_System);
+                    }
+                }
+                object[] _outp = null;
+                if (_params != null && _params.Length > 0)
+                {
+                    _outp = new object[_params.Length];
+                    var _paramsdef = method_System.GetParameters();
+                    for (int i = 0; i < _params.Length; i++)
+                    {
+                        if (_params[i] == null)
+                            _outp[i] = null;
+                        Type tsrc = _params[i].GetType();
+                        Type ttarget = _paramsdef[i].ParameterType;
+                        if (tsrc == ttarget)
+                        {
+                            _outp[i] = _params[i];
+                        }
+                        else if (tsrc.IsSubclassOf(ttarget))
+                        {
+                            _outp[i] = _params[i];
+                        }
+                        else
+                        {
+                            if (ttarget == typeof(byte))
+                                _outp[i] = (byte)Convert.ToDecimal(_params[i]);
+                            else
+                            {
+                                _outp[i] = _params[i];
+                            }
+                            //var ms =_params[i].GetType().GetMethods();
+                        }
+                    }
+                }
+                var newobj = (method_System as System.Reflection.ConstructorInfo).Invoke(_outp);
+                return newobj;
+            }
+            else
+            {
+                //if (method_System.DeclaringType.IsSubclassOf(typeof(Delegate)))//直接用Delegate.Invoke,会导致转到本机代码再回来
+                ////会导致错误堆栈不方便观察,但是也没办法直接调用,只能手写一些常用类型
+                //{
+                //    //需要从Delegate转换成实际类型执行的帮助类
+                //    Action<int> abc = _this as Action<int>;
+                //    abc((int)_params[0]);
+                //    return null;
+                //}
+                //else
+                {
+                    return method_System.Invoke(_this, _params);
+                }
+            }
+
+        }
+
+        public object Invoke(ThreadContext context, object _this, object[] _params, bool bVisual, bool autoLogDump)
+        {
+            try
+            {
+                return Invoke(context, _this, _params);
+            }
+            catch(Exception err)
+            {
+                if (context == null) context = ThreadContext.activeContext;
+                if (context == null)
+                    throw new Exception("当前线程没有创建ThreadContext,无法Dump", err);
+                else
+                {
+                    context.environment.logger.Log_Error("Error InSystemCall:" + this.DeclaringType.FullName + "::" + this.Name);
+                    throw err;
+                }
+            }
+        }
+
+    }
+
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/Type/System/System_Type.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 9df6666293942014bbd459c9e2eafa90
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 145 - 0
Unity/Assets/Plugins/CLRSharp/Type/Type_Common.cs

@@ -0,0 +1,145 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    //一个ICLRType 是一个所有类型的抽象,无论是System.Type
+    //还是CLRSharp的抽象,均可通过ICLRType进行调用
+    public interface ICLRType
+    {
+        ICLRSharp_Environment env
+        {
+            get;
+        }
+        string Name
+        {
+            get;
+        }
+        string FullName
+        {
+            get;
+        }
+        string FullNameWithAssembly
+        {
+            get;
+        }
+        System.Type TypeForSystem
+        {
+            get;
+        }
+        //funcname==".ctor" 表示构造函数
+        IMethod GetMethod(string funcname, MethodParamList types);
+        object InitObj();
+        /// <summary>
+        /// 获取模板函数
+        /// </summary>
+        /// <param name="funcname"></param>
+        /// <param name="TTypes"></param>
+        /// <param name="types"></param>
+        /// <returns></returns>
+        IMethod GetMethodT(string funcname, MethodParamList TTypes, MethodParamList types);
+
+        IField GetField(string name);
+        string[] GetFieldNames();
+        bool IsInst(object obj);
+
+        ICLRType GetNestType(ICLRSharp_Environment env, string fullname);
+        ICLRType[] SubTypes
+        {
+            get;
+        }
+    }
+    public interface ICLRType_Sharp : ICLRType
+    {
+        CLRSharp_Instance staticInstance
+        {
+            get;
+        }
+        void ResetStaticInstace();
+        bool NeedCCtor
+        {
+            get;
+        }
+        void InvokeCCtor(ThreadContext context);
+        Mono.Cecil.TypeDefinition type_CLRSharp
+        {
+            get;
+        }
+        IMethod GetVMethod(IMethod _base);
+
+        bool ContainBase(Type t);
+        bool HasSysBase
+        {
+            get;
+        }
+        string[] GetMethodNames();
+    }
+    public interface ICLRType_System : ICLRType
+    {
+        Delegate CreateDelegate(Type deletype, object _this, IMethod_System _method);
+    }
+    public interface IMethod
+    {
+        object Invoke(ThreadContext context, object _this, object[] _params);
+        object Invoke(ThreadContext context, object _this, object[] _params,bool bVisual);
+
+        object Invoke(ThreadContext context, object _this, object[] _params, bool bVisual,bool autoLogDump);
+
+        bool isStatic
+        {
+            get;
+        }
+        string Name
+        {
+            get;
+        }
+
+        ICLRType DeclaringType
+        {
+            get;
+        }
+        ICLRType ReturnType
+        {
+            get;
+        }
+        MethodParamList ParamList
+        {
+            get;
+        }
+    }
+    public interface IMethod_System : IMethod
+    {
+        System.Reflection.MethodBase method_System
+        {
+            get;
+        }
+    }
+    public interface IMethod_Sharp : IMethod
+    {
+        CodeBody body
+        {
+            get;
+        }
+
+    }
+    public interface IField
+    {
+        void Set(object _this, object value);
+        object Get(object _this);
+        bool isStatic
+        {
+            get;
+        }
+        ICLRType DeclaringType
+        {
+            get;
+
+        }
+        ICLRType FieldType
+        {
+            get;
+        }
+    }
+
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/Type/Type_Common.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 6502218e88187b54f80e4b3f1bf61590
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 171 - 0
Unity/Assets/Plugins/CLRSharp/Type/Type_List.cs

@@ -0,0 +1,171 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CLRSharp
+{
+    /// <summary>
+    /// 方法参数表
+    /// </summary>
+    public class MethodParamList : List<ICLRType>
+    {
+        private MethodParamList()
+        {
+
+        }
+        private MethodParamList(IList<ICLRType> types)
+        {
+            if(types!=null)
+            {
+                foreach(var t in types)
+                {
+                    this.Add(t);
+                }
+            }
+
+        }
+        static MethodParamList _OneParam_Int = null;
+        public static MethodParamList const_OneParam_Int(ICLRSharp_Environment env)
+        {
+            if (_OneParam_Int == null)
+            {
+                _OneParam_Int = new MethodParamList(new ICLRType[]{env.GetType(typeof(int))});
+            }
+
+            return _OneParam_Int;
+
+
+        }
+        static MethodParamList _ZeroParam = null;
+        public static MethodParamList constEmpty()
+        {
+            if (_ZeroParam == null)
+            {
+                _ZeroParam = new MethodParamList(new ICLRType[] { });
+            }
+            return _ZeroParam;
+        }
+
+        public static MethodParamList Make(params ICLRType[] types)
+        {
+            return new MethodParamList(types);
+        }
+        public MethodParamList(ICLRSharp_Environment env, Mono.Cecil.MethodReference method)
+        {
+            if (method.HasParameters)
+            {
+                Mono.Cecil.GenericInstanceType _typegen = null;
+                _typegen = method.DeclaringType as Mono.Cecil.GenericInstanceType;
+                Mono.Cecil.GenericInstanceMethod gm = method as Mono.Cecil.GenericInstanceMethod;
+                MethodParamList _methodgen = null;
+                if (gm != null)
+                    _methodgen = new MethodParamList(env, gm);
+                foreach (var p in method.Parameters)
+                {
+                    string paramname = p.ParameterType.FullName;
+
+                    if (p.ParameterType.IsGenericParameter)
+                    {
+                        if (p.ParameterType.Name.Contains("!!"))
+                        {
+                            int index = int.Parse(p.ParameterType.Name.Substring(2));
+                            paramname = _methodgen[index].FullName;
+                        }
+                        else if (p.ParameterType.Name.Contains("!"))
+                        {
+                            int index = int.Parse(p.ParameterType.Name.Substring(1));
+                            paramname = _typegen.GenericArguments[index].FullName;
+                        }
+                    }
+
+                    if (paramname.Contains("!!"))
+                    {
+                        this.Add(GetTType(env, p, _methodgen));
+                    }
+                    else
+                    {
+                        this.Add(env.GetType(paramname));
+                    }
+                }
+            }
+        }
+        public MethodParamList(ICLRSharp_Environment env, Mono.Collections.Generic.Collection<Mono.Cecil.Cil.VariableDefinition> ps)
+        {
+            foreach (var p in ps)
+            {
+                string paramname = p.VariableType.FullName;
+
+                this.Add(env.GetType(paramname));
+
+            }
+        }
+        static ICLRType GetTType(ICLRSharp_Environment env, Mono.Cecil.ParameterDefinition param, MethodParamList _methodgen)
+        {
+            string typename = param.ParameterType.FullName;
+            for (int i = 0; i < _methodgen.Count; i++)
+            {
+                string p = "!!" + i.ToString();
+                typename = typename.Replace(p, _methodgen[i].FullName);
+            }
+            return env.GetType(typename);
+        }
+        public MethodParamList(ICLRSharp_Environment env, Mono.Cecil.GenericInstanceMethod method)
+        {
+            foreach (var p in method.GenericArguments)
+            {
+                string paramname = p.FullName;
+                if (p.IsGenericParameter)
+                {
+
+                    var typegen = method.DeclaringType as Mono.Cecil.GenericInstanceType;
+                    if (p.Name[0] == '!')
+                    {
+                        int index = int.Parse(p.Name.Substring(1));
+                        paramname = typegen.GenericArguments[index].FullName;
+                    }
+                }
+                this.Add(env.GetType(paramname));
+            }
+        }
+
+        public MethodParamList(ICLRSharp_Environment env, System.Reflection.MethodBase method)
+        {
+            foreach (var p in method.GetParameters())
+            {
+                this.Add(env.GetType(p.ParameterType));
+            }
+        }
+        public override int GetHashCode()
+        {
+            return this.ToString().GetHashCode();
+        }
+        public override string ToString()
+        {
+            if (name == null)
+            {
+                name = "";
+                foreach (var t in this)
+                {
+                    name += t.ToString() + ";";
+                }
+            }
+            return name;
+        }
+        string name = null;
+        System.Type[] SystemType = null;
+        public System.Type[] ToArraySystem()
+        {
+            if (SystemType == null)
+            {
+                SystemType = new System.Type[this.Count];
+                for (int i = 0; i < this.Count; i++)
+                {
+
+                    SystemType[i] = this[i].TypeForSystem;
+                }
+            }
+            return SystemType;
+        }
+    }
+
+}

+ 8 - 0
Unity/Assets/Plugins/CLRSharp/Type/Type_List.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 455fe6a3c8ea71945aeaeeed401221d1
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/Libs.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: 02e9cecb7c4652d4cbe5eb6444de3a34
+folderAsset: yes
+DefaultImporter:
+  userData: 

BIN
Unity/Assets/Plugins/Libs/Mono.Cecil.Mdb.dll


+ 7 - 0
Unity/Assets/Plugins/Libs/Mono.Cecil.Mdb.dll.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 341a2dcb8d96096479ca8dd5d0536cc4
+MonoAssemblyImporter:
+  serializedVersion: 1
+  iconMap: {}
+  executionOrder: {}
+  userData: 

BIN
Unity/Assets/Plugins/Libs/Mono.Cecil.dll


+ 7 - 0
Unity/Assets/Plugins/Libs/Mono.Cecil.dll.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 21b9ce1cdff60e14a964b44528c1cc43
+MonoAssemblyImporter:
+  serializedVersion: 1
+  iconMap: {}
+  executionOrder: {}
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: f07d878000a4d974493454ed8811de98
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: 346a9c57372d0fb41a972419f40d4019
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 249 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitAccess.cs

@@ -0,0 +1,249 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+using System.IO;
+using System.Text;
+
+namespace Microsoft.Cci.Pdb {
+  internal class BitAccess {
+
+    internal BitAccess(int capacity) {
+      this.buffer = new byte[capacity];
+    }
+
+    internal byte[] Buffer {
+      get { return buffer; }
+    }
+    private byte[] buffer;
+
+    internal void FillBuffer(Stream stream, int capacity) {
+      MinCapacity(capacity);
+      stream.Read(buffer, 0, capacity);
+      offset = 0;
+    }
+
+    internal void Append(Stream stream, int count) {
+      int newCapacity = offset + count;
+      if (buffer.Length < newCapacity) {
+        byte[] newBuffer = new byte[newCapacity];
+        Array.Copy(buffer, newBuffer, buffer.Length);
+        buffer = newBuffer;
+      }
+      stream.Read(buffer, offset, count);
+      offset += count;
+    }
+
+    internal int Position {
+      get { return offset; }
+      set { offset = value; }
+    }
+    private int offset;
+
+    //internal void WriteBuffer(Stream stream, int count) {
+    //  stream.Write(buffer, 0, count);
+    //}
+
+    internal void MinCapacity(int capacity) {
+      if (buffer.Length < capacity) {
+        buffer = new byte[capacity];
+      }
+      offset = 0;
+    }
+
+    internal void Align(int alignment) {
+      while ((offset % alignment) != 0) {
+        offset++;
+      }
+    }
+
+    //internal void WriteInt32(int value) {
+    //  buffer[offset + 0] = (byte)value;
+    //  buffer[offset + 1] = (byte)(value >> 8);
+    //  buffer[offset + 2] = (byte)(value >> 16);
+    //  buffer[offset + 3] = (byte)(value >> 24);
+    //  offset += 4;
+    //}
+
+    //internal void WriteInt32(int[] values) {
+    //  for (int i = 0; i < values.Length; i++) {
+    //    WriteInt32(values[i]);
+    //  }
+    //}
+
+    //internal void WriteBytes(byte[] bytes) {
+    //  for (int i = 0; i < bytes.Length; i++) {
+    //    buffer[offset++] = bytes[i];
+    //  }
+    //}
+
+    internal void ReadInt16(out short value) {
+      value = (short)((buffer[offset + 0] & 0xFF) |
+                            (buffer[offset + 1] << 8));
+      offset += 2;
+    }
+
+    internal void ReadInt8(out sbyte value) {
+      value = (sbyte)buffer[offset];
+      offset += 1;
+    }
+
+    internal void ReadInt32(out int value) {
+      value = (int)((buffer[offset + 0] & 0xFF) |
+                          (buffer[offset + 1] << 8) |
+                          (buffer[offset + 2] << 16) |
+                          (buffer[offset + 3] << 24));
+      offset += 4;
+    }
+
+    internal void ReadInt64(out long value) {
+      value = (long)(((ulong)buffer[offset + 0] & 0xFF) |
+                           ((ulong)buffer[offset + 1] << 8) |
+                           ((ulong)buffer[offset + 2] << 16) |
+                           ((ulong)buffer[offset + 3] << 24) |
+                           ((ulong)buffer[offset + 4] << 32) |
+                           ((ulong)buffer[offset + 5] << 40) |
+                           ((ulong)buffer[offset + 6] << 48) |
+                           ((ulong)buffer[offset + 7] << 56));
+      offset += 8;
+    }
+
+    internal void ReadUInt16(out ushort value) {
+      value = (ushort)((buffer[offset + 0] & 0xFF) |
+                             (buffer[offset + 1] << 8));
+      offset += 2;
+    }
+
+    internal void ReadUInt8(out byte value) {
+      value = (byte)((buffer[offset + 0] & 0xFF));
+      offset += 1;
+    }
+
+    internal void ReadUInt32(out uint value) {
+      value = (uint)((buffer[offset + 0] & 0xFF) |
+                           (buffer[offset + 1] << 8) |
+                           (buffer[offset + 2] << 16) |
+                           (buffer[offset + 3] << 24));
+      offset += 4;
+    }
+
+    internal void ReadUInt64(out ulong value) {
+      value = (ulong)(((ulong)buffer[offset + 0] & 0xFF) |
+                           ((ulong)buffer[offset + 1] << 8) |
+                           ((ulong)buffer[offset + 2] << 16) |
+                           ((ulong)buffer[offset + 3] << 24) |
+                           ((ulong)buffer[offset + 4] << 32) |
+                           ((ulong)buffer[offset + 5] << 40) |
+                           ((ulong)buffer[offset + 6] << 48) |
+                           ((ulong)buffer[offset + 7] << 56));
+      offset += 8;
+    }
+
+    internal void ReadInt32(int[] values) {
+      for (int i = 0; i < values.Length; i++) {
+        ReadInt32(out values[i]);
+      }
+    }
+
+    internal void ReadUInt32(uint[] values) {
+      for (int i = 0; i < values.Length; i++) {
+        ReadUInt32(out values[i]);
+      }
+    }
+
+    internal void ReadBytes(byte[] bytes) {
+      for (int i = 0; i < bytes.Length; i++) {
+        bytes[i] = buffer[offset++];
+      }
+    }
+
+    internal float ReadFloat() {
+      float result = BitConverter.ToSingle(buffer, offset);
+      offset += 4;
+      return result;
+    }
+
+    internal double ReadDouble() {
+      double result = BitConverter.ToDouble(buffer, offset);
+      offset += 8;
+      return result;
+    }
+
+    internal decimal ReadDecimal() {
+      int[] bits = new int[4];
+      this.ReadInt32(bits);
+      return new decimal(bits[2], bits[3], bits[1], bits[0] < 0, (byte)((bits[0] & 0x00FF0000) >> 16));
+    }
+
+    internal void ReadBString(out string value) {
+      ushort len;
+      this.ReadUInt16(out len);
+      value = Encoding.UTF8.GetString(buffer, offset, len);
+      offset += len;
+    }
+
+    internal void ReadCString(out string value) {
+      int len = 0;
+      while (offset + len < buffer.Length && buffer[offset + len] != 0) {
+        len++;
+      }
+      value = Encoding.UTF8.GetString(buffer, offset, len);
+      offset += len + 1;
+    }
+
+    internal void SkipCString(out string value) {
+      int len = 0;
+      while (offset + len < buffer.Length && buffer[offset + len] != 0) {
+        len++;
+      }
+      offset += len + 1;
+      value= null;
+    }
+
+    internal void ReadGuid(out Guid guid) {
+      uint a;
+      ushort b;
+      ushort c;
+      byte d;
+      byte e;
+      byte f;
+      byte g;
+      byte h;
+      byte i;
+      byte j;
+      byte k;
+
+      ReadUInt32(out a);
+      ReadUInt16(out b);
+      ReadUInt16(out c);
+      ReadUInt8(out d);
+      ReadUInt8(out e);
+      ReadUInt8(out f);
+      ReadUInt8(out g);
+      ReadUInt8(out h);
+      ReadUInt8(out i);
+      ReadUInt8(out j);
+      ReadUInt8(out k);
+
+      guid = new Guid(a, b, c, d, e, f, g, h, i, j, k);
+    }
+
+    internal string ReadString() {
+      int len = 0;
+      while (offset + len < buffer.Length && buffer[offset + len] != 0) {
+        len+=2;
+      }
+      string result = Encoding.Unicode.GetString(buffer, offset, len);
+      offset += len + 2;
+      return result;
+    }
+
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitAccess.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e40644f20bb745945b193586d4b9a30f
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 74 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitSet.cs

@@ -0,0 +1,74 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal struct BitSet {
+    internal BitSet(BitAccess bits) {
+      bits.ReadInt32(out size);    // 0..3 : Number of words
+      words = new uint[size];
+      bits.ReadUInt32(words);
+    }
+
+    //internal BitSet(int size) {
+    //  this.size = size;
+    //  words = new uint[size];
+    //}
+
+    internal bool IsSet(int index) {
+      int word = index / 32;
+      if (word >= this.size) return false;
+      return ((words[word] & GetBit(index)) != 0);
+    }
+
+    //internal void Set(int index) {
+    //  int word = index / 32;
+    //  if (word >= this.size) return;
+    //  words[word] |= GetBit(index);
+    //}
+
+    //internal void Clear(int index) {
+    //  int word = index / 32;
+    //  if (word >= this.size) return;
+    //  words[word] &= ~GetBit(index);
+    //}
+
+    private static uint GetBit(int index) {
+      return ((uint)1 << (index % 32));
+    }
+
+    //private static uint ReverseBits(uint value) {
+    //  uint o = 0;
+    //  for (int i = 0; i < 32; i++) {
+    //    o = (o << 1) | (value & 1);
+    //    value >>= 1;
+    //  }
+    //  return o;
+    //}
+
+    internal bool IsEmpty {
+      get { return size == 0; }
+    }
+
+    //internal bool GetWord(int index, out uint word) {
+    //  if (index < size) {
+    //    word = ReverseBits(words[index]);
+    //    return true;
+    //  }
+    //  word = 0;
+    //  return false;
+    //}
+
+    private int size;
+    private uint[] words;
+  }
+
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitSet.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 19ecf2301b92d4044b3fc036bf12f2cc
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 2435 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/CvInfo.cs

@@ -0,0 +1,2435 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+//
+//  File:   CvInfo.cs
+//
+//  Generic CodeView information definitions
+//
+//  Structures, constants, etc. for accessing and interpreting
+//  CodeView information.
+//
+//  The master copy of this file resides in the langapi project (in C++).
+//  All Microsoft projects are required to use the master copy without
+//  modification.  Modification of the master version or a copy
+//  without consultation with all parties concerned is extremely
+//  risky.
+//
+//  When this file is modified, the corresponding documentation file
+//  omfdeb.doc in the langapi project must be updated.
+//
+//  This is a read-only copy of the C++ file converted to C#.
+//
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal struct FLOAT10 {
+    internal byte Data_0;
+    internal byte Data_1;
+    internal byte Data_2;
+    internal byte Data_3;
+    internal byte Data_4;
+    internal byte Data_5;
+    internal byte Data_6;
+    internal byte Data_7;
+    internal byte Data_8;
+    internal byte Data_9;
+  };
+
+  internal enum CV_SIGNATURE {
+    C6=0,    // Actual signature is >64K
+    C7=1,    // First explicit signature
+    C11=2,    // C11 (vc5.x) 32-bit types
+    C13=4,    // C13 (vc7.x) zero terminated names
+    RESERVERD=5,    // All signatures from 5 to 64K are reserved
+  };
+
+  //  CodeView Symbol and Type OMF type information is broken up into two
+  //  ranges.  Type indices less than 0x1000 describe type information
+  //  that is frequently used.  Type indices above 0x1000 are used to
+  //  describe more complex features such as functions, arrays and
+  //  structures.
+  //
+
+  //  Primitive types have predefined meaning that is encoded in the
+  //  values of the various bit fields in the value.
+  //
+  //  A CodeView primitive type is defined as:
+  //
+  //  1 1
+  //  1 089  7654  3  210
+  //  r mode type  r  sub
+  //
+  //  Where
+  //      mode is the pointer mode
+  //      type is a type indicator
+  //      sub  is a subtype enumeration
+  //      r    is a reserved field
+  //
+  //  See Microsoft Symbol and Type OMF (Version 4.0) for more
+  //  information.
+  //
+
+  //  pointer mode enumeration values
+
+  internal enum CV_prmode {
+    CV_TM_DIRECT=0,        // mode is not a pointer
+    CV_TM_NPTR32=4,        // mode is a 32 bit near pointer
+    CV_TM_NPTR64=6,        // mode is a 64 bit near pointer
+    CV_TM_NPTR128=7,        // mode is a 128 bit near pointer
+  };
+
+  //  type enumeration values
+
+  internal enum CV_type {
+    CV_SPECIAL=0x00,     // special type size values
+    CV_SIGNED=0x01,     // signed integral size values
+    CV_UNSIGNED=0x02,     // unsigned integral size values
+    CV_BOOLEAN=0x03,     // Boolean size values
+    CV_REAL=0x04,     // real number size values
+    CV_COMPLEX=0x05,     // complex number size values
+    CV_SPECIAL2=0x06,     // second set of special types
+    CV_INT=0x07,     // integral (int) values
+    CV_CVRESERVED=0x0f,
+  };
+
+  //  subtype enumeration values for CV_SPECIAL
+
+  internal enum CV_special {
+    CV_SP_NOTYPE=0x00,
+    CV_SP_ABS=0x01,
+    CV_SP_SEGMENT=0x02,
+    CV_SP_VOID=0x03,
+    CV_SP_CURRENCY=0x04,
+    CV_SP_NBASICSTR=0x05,
+    CV_SP_FBASICSTR=0x06,
+    CV_SP_NOTTRANS=0x07,
+    CV_SP_HRESULT=0x08,
+  };
+
+  //  subtype enumeration values for CV_SPECIAL2
+
+  internal enum CV_special2 {
+    CV_S2_BIT=0x00,
+    CV_S2_PASCHAR=0x01,     // Pascal CHAR
+  };
+
+  //  subtype enumeration values for CV_SIGNED, CV_UNSIGNED and CV_BOOLEAN
+
+  internal enum CV_integral {
+    CV_IN_1BYTE=0x00,
+    CV_IN_2BYTE=0x01,
+    CV_IN_4BYTE=0x02,
+    CV_IN_8BYTE=0x03,
+    CV_IN_16BYTE=0x04,
+  };
+
+  //  subtype enumeration values for CV_REAL and CV_COMPLEX
+
+  internal enum CV_real {
+    CV_RC_REAL32=0x00,
+    CV_RC_REAL64=0x01,
+    CV_RC_REAL80=0x02,
+    CV_RC_REAL128=0x03,
+  };
+
+  //  subtype enumeration values for CV_INT (really int)
+
+  internal enum CV_int {
+    CV_RI_CHAR=0x00,
+    CV_RI_INT1=0x00,
+    CV_RI_WCHAR=0x01,
+    CV_RI_UINT1=0x01,
+    CV_RI_INT2=0x02,
+    CV_RI_UINT2=0x03,
+    CV_RI_INT4=0x04,
+    CV_RI_UINT4=0x05,
+    CV_RI_INT8=0x06,
+    CV_RI_UINT8=0x07,
+    CV_RI_INT16=0x08,
+    CV_RI_UINT16=0x09,
+  };
+
+  internal struct CV_PRIMITIVE_TYPE {
+    const uint CV_MMASK     = 0x700;       // mode mask
+    const uint CV_TMASK     = 0x0f0;       // type mask
+    const uint CV_SMASK     = 0x00f;       // subtype mask
+
+    const int CV_MSHIFT     = 8;           // primitive mode right shift count
+    const int CV_TSHIFT     = 4;           // primitive type right shift count
+    const int CV_SSHIFT     = 0;           // primitive subtype right shift count
+
+    // function to extract primitive mode, type and size
+
+    //internal static CV_prmode CV_MODE(TYPE_ENUM typ) {
+    //  return (CV_prmode)((((uint)typ) & CV_MMASK) >> CV_MSHIFT);
+    //}
+
+    //internal static CV_type CV_TYPE(TYPE_ENUM typ) {
+    //  return (CV_type)((((uint)typ) & CV_TMASK) >> CV_TSHIFT);
+    //}
+
+    //internal static uint CV_SUBT(TYPE_ENUM typ) {
+    //  return ((((uint)typ) & CV_SMASK) >> CV_SSHIFT);
+    //}
+
+    // functions to check the type of a primitive
+
+    //internal static bool CV_TYP_IS_DIRECT(TYPE_ENUM typ) {
+    //  return (CV_MODE(typ) == CV_prmode.CV_TM_DIRECT);
+    //}
+
+    //internal static bool CV_TYP_IS_PTR(TYPE_ENUM typ) {
+    //  return (CV_MODE(typ) != CV_prmode.CV_TM_DIRECT);
+    //}
+
+    //internal static bool CV_TYP_IS_SIGNED(TYPE_ENUM typ) {
+    //  return
+    //      (((CV_TYPE(typ) == CV_type.CV_SIGNED) && CV_TYP_IS_DIRECT(typ)) ||
+    //             (typ == TYPE_ENUM.T_INT1)  ||
+    //             (typ == TYPE_ENUM.T_INT2)  ||
+    //             (typ == TYPE_ENUM.T_INT4)  ||
+    //             (typ == TYPE_ENUM.T_INT8)  ||
+    //             (typ == TYPE_ENUM.T_INT16) ||
+    //             (typ == TYPE_ENUM.T_RCHAR));
+    //}
+
+    //internal static bool CV_TYP_IS_UNSIGNED(TYPE_ENUM typ) {
+    //  return (((CV_TYPE(typ) == CV_type.CV_UNSIGNED) && CV_TYP_IS_DIRECT(typ)) ||
+    //                (typ == TYPE_ENUM.T_UINT1) ||
+    //                (typ == TYPE_ENUM.T_UINT2) ||
+    //                (typ == TYPE_ENUM.T_UINT4) ||
+    //                (typ == TYPE_ENUM.T_UINT8) ||
+    //                (typ == TYPE_ENUM.T_UINT16));
+    //}
+
+    //internal static bool CV_TYP_IS_REAL(TYPE_ENUM typ) {
+    //  return ((CV_TYPE(typ) == CV_type.CV_REAL)  && CV_TYP_IS_DIRECT(typ));
+    //}
+
+    const uint CV_FIRST_NONPRIM = 0x1000;
+
+    //internal static bool CV_IS_PRIMITIVE(TYPE_ENUM typ) {
+    //  return ((uint)(typ) < CV_FIRST_NONPRIM);
+    //}
+
+    //internal static bool CV_TYP_IS_COMPLEX(TYPE_ENUM typ) {
+    //  return ((CV_TYPE(typ) == CV_type.CV_COMPLEX) && CV_TYP_IS_DIRECT(typ));
+    //}
+
+    //internal static bool CV_IS_INTERNAL_PTR(TYPE_ENUM typ) {
+    //  return (CV_IS_PRIMITIVE(typ) &&
+    //                CV_TYPE(typ) == CV_type.CV_CVRESERVED &&
+    //                CV_TYP_IS_PTR(typ));
+    //}
+  }
+
+  // selected values for type_index - for a more complete definition, see
+  // Microsoft Symbol and Type OMF document
+
+  //  Special Types
+
+  internal enum TYPE_ENUM {
+    //  Special Types
+
+    T_NOTYPE=0x0000,   // uncharacterized type (no type)
+    T_ABS=0x0001,   // absolute symbol
+    T_SEGMENT=0x0002,   // segment type
+    T_VOID=0x0003,   // void
+    T_HRESULT=0x0008,   // OLE/COM HRESULT
+    T_32PHRESULT=0x0408,   // OLE/COM HRESULT __ptr32//
+    T_64PHRESULT=0x0608,   // OLE/COM HRESULT __ptr64//
+    T_PVOID=0x0103,   // near pointer to void
+    T_PFVOID=0x0203,   // far pointer to void
+    T_PHVOID=0x0303,   // huge pointer to void
+    T_32PVOID=0x0403,   // 32 bit pointer to void
+    T_64PVOID=0x0603,   // 64 bit pointer to void
+    T_CURRENCY=0x0004,   // BASIC 8 byte currency value
+    T_NOTTRANS=0x0007,   // type not translated by cvpack
+    T_BIT=0x0060,   // bit
+    T_PASCHAR=0x0061,   // Pascal CHAR
+
+    //  Character types
+
+    T_CHAR=0x0010,   // 8 bit signed
+    T_32PCHAR=0x0410,   // 32 bit pointer to 8 bit signed
+    T_64PCHAR=0x0610,   // 64 bit pointer to 8 bit signed
+
+    T_UCHAR=0x0020,   // 8 bit unsigned
+    T_32PUCHAR=0x0420,   // 32 bit pointer to 8 bit unsigned
+    T_64PUCHAR=0x0620,   // 64 bit pointer to 8 bit unsigned
+
+    //  really a character types
+
+    T_RCHAR=0x0070,   // really a char
+    T_32PRCHAR=0x0470,   // 32 bit pointer to a real char
+    T_64PRCHAR=0x0670,   // 64 bit pointer to a real char
+
+    //  really a wide character types
+
+    T_WCHAR=0x0071,   // wide char
+    T_32PWCHAR=0x0471,   // 32 bit pointer to a wide char
+    T_64PWCHAR=0x0671,   // 64 bit pointer to a wide char
+
+    //  8 bit int types
+
+    T_INT1=0x0068,   // 8 bit signed int
+    T_32PINT1=0x0468,   // 32 bit pointer to 8 bit signed int
+    T_64PINT1=0x0668,   // 64 bit pointer to 8 bit signed int
+
+    T_UINT1=0x0069,   // 8 bit unsigned int
+    T_32PUINT1=0x0469,   // 32 bit pointer to 8 bit unsigned int
+    T_64PUINT1=0x0669,   // 64 bit pointer to 8 bit unsigned int
+
+    //  16 bit short types
+
+    T_SHORT=0x0011,   // 16 bit signed
+    T_32PSHORT=0x0411,   // 32 bit pointer to 16 bit signed
+    T_64PSHORT=0x0611,   // 64 bit pointer to 16 bit signed
+
+    T_USHORT=0x0021,   // 16 bit unsigned
+    T_32PUSHORT=0x0421,   // 32 bit pointer to 16 bit unsigned
+    T_64PUSHORT=0x0621,   // 64 bit pointer to 16 bit unsigned
+
+    //  16 bit int types
+
+    T_INT2=0x0072,   // 16 bit signed int
+    T_32PINT2=0x0472,   // 32 bit pointer to 16 bit signed int
+    T_64PINT2=0x0672,   // 64 bit pointer to 16 bit signed int
+
+    T_UINT2=0x0073,   // 16 bit unsigned int
+    T_32PUINT2=0x0473,   // 32 bit pointer to 16 bit unsigned int
+    T_64PUINT2=0x0673,   // 64 bit pointer to 16 bit unsigned int
+
+    //  32 bit long types
+
+    T_LONG=0x0012,   // 32 bit signed
+    T_ULONG=0x0022,   // 32 bit unsigned
+    T_32PLONG=0x0412,   // 32 bit pointer to 32 bit signed
+    T_32PULONG=0x0422,   // 32 bit pointer to 32 bit unsigned
+    T_64PLONG=0x0612,   // 64 bit pointer to 32 bit signed
+    T_64PULONG=0x0622,   // 64 bit pointer to 32 bit unsigned
+
+    //  32 bit int types
+
+    T_INT4=0x0074,   // 32 bit signed int
+    T_32PINT4=0x0474,   // 32 bit pointer to 32 bit signed int
+    T_64PINT4=0x0674,   // 64 bit pointer to 32 bit signed int
+
+    T_UINT4=0x0075,   // 32 bit unsigned int
+    T_32PUINT4=0x0475,   // 32 bit pointer to 32 bit unsigned int
+    T_64PUINT4=0x0675,   // 64 bit pointer to 32 bit unsigned int
+
+    //  64 bit quad types
+
+    T_QUAD=0x0013,   // 64 bit signed
+    T_32PQUAD=0x0413,   // 32 bit pointer to 64 bit signed
+    T_64PQUAD=0x0613,   // 64 bit pointer to 64 bit signed
+
+    T_UQUAD=0x0023,   // 64 bit unsigned
+    T_32PUQUAD=0x0423,   // 32 bit pointer to 64 bit unsigned
+    T_64PUQUAD=0x0623,   // 64 bit pointer to 64 bit unsigned
+
+    //  64 bit int types
+
+    T_INT8=0x0076,   // 64 bit signed int
+    T_32PINT8=0x0476,   // 32 bit pointer to 64 bit signed int
+    T_64PINT8=0x0676,   // 64 bit pointer to 64 bit signed int
+
+    T_UINT8=0x0077,   // 64 bit unsigned int
+    T_32PUINT8=0x0477,   // 32 bit pointer to 64 bit unsigned int
+    T_64PUINT8=0x0677,   // 64 bit pointer to 64 bit unsigned int
+
+    //  128 bit octet types
+
+    T_OCT=0x0014,   // 128 bit signed
+    T_32POCT=0x0414,   // 32 bit pointer to 128 bit signed
+    T_64POCT=0x0614,   // 64 bit pointer to 128 bit signed
+
+    T_UOCT=0x0024,   // 128 bit unsigned
+    T_32PUOCT=0x0424,   // 32 bit pointer to 128 bit unsigned
+    T_64PUOCT=0x0624,   // 64 bit pointer to 128 bit unsigned
+
+    //  128 bit int types
+
+    T_INT16=0x0078,   // 128 bit signed int
+    T_32PINT16=0x0478,   // 32 bit pointer to 128 bit signed int
+    T_64PINT16=0x0678,   // 64 bit pointer to 128 bit signed int
+
+    T_UINT16=0x0079,   // 128 bit unsigned int
+    T_32PUINT16=0x0479,   // 32 bit pointer to 128 bit unsigned int
+    T_64PUINT16=0x0679,   // 64 bit pointer to 128 bit unsigned int
+
+    //  32 bit real types
+
+    T_REAL32=0x0040,   // 32 bit real
+    T_32PREAL32=0x0440,   // 32 bit pointer to 32 bit real
+    T_64PREAL32=0x0640,   // 64 bit pointer to 32 bit real
+
+    //  64 bit real types
+
+    T_REAL64=0x0041,   // 64 bit real
+    T_32PREAL64=0x0441,   // 32 bit pointer to 64 bit real
+    T_64PREAL64=0x0641,   // 64 bit pointer to 64 bit real
+
+    //  80 bit real types
+
+    T_REAL80=0x0042,   // 80 bit real
+    T_32PREAL80=0x0442,   // 32 bit pointer to 80 bit real
+    T_64PREAL80=0x0642,   // 64 bit pointer to 80 bit real
+
+    //  128 bit real types
+
+    T_REAL128=0x0043,   // 128 bit real
+    T_32PREAL128=0x0443,   // 32 bit pointer to 128 bit real
+    T_64PREAL128=0x0643,   // 64 bit pointer to 128 bit real
+
+    //  32 bit complex types
+
+    T_CPLX32=0x0050,   // 32 bit complex
+    T_32PCPLX32=0x0450,   // 32 bit pointer to 32 bit complex
+    T_64PCPLX32=0x0650,   // 64 bit pointer to 32 bit complex
+
+    //  64 bit complex types
+
+    T_CPLX64=0x0051,   // 64 bit complex
+    T_32PCPLX64=0x0451,   // 32 bit pointer to 64 bit complex
+    T_64PCPLX64=0x0651,   // 64 bit pointer to 64 bit complex
+
+    //  80 bit complex types
+
+    T_CPLX80=0x0052,   // 80 bit complex
+    T_32PCPLX80=0x0452,   // 32 bit pointer to 80 bit complex
+    T_64PCPLX80=0x0652,   // 64 bit pointer to 80 bit complex
+
+    //  128 bit complex types
+
+    T_CPLX128=0x0053,   // 128 bit complex
+    T_32PCPLX128=0x0453,   // 32 bit pointer to 128 bit complex
+    T_64PCPLX128=0x0653,   // 64 bit pointer to 128 bit complex
+
+    //  boolean types
+
+    T_BOOL08=0x0030,   // 8 bit boolean
+    T_32PBOOL08=0x0430,   // 32 bit pointer to 8 bit boolean
+    T_64PBOOL08=0x0630,   // 64 bit pointer to 8 bit boolean
+
+    T_BOOL16=0x0031,   // 16 bit boolean
+    T_32PBOOL16=0x0431,   // 32 bit pointer to 18 bit boolean
+    T_64PBOOL16=0x0631,   // 64 bit pointer to 18 bit boolean
+
+    T_BOOL32=0x0032,   // 32 bit boolean
+    T_32PBOOL32=0x0432,   // 32 bit pointer to 32 bit boolean
+    T_64PBOOL32=0x0632,   // 64 bit pointer to 32 bit boolean
+
+    T_BOOL64=0x0033,   // 64 bit boolean
+    T_32PBOOL64=0x0433,   // 32 bit pointer to 64 bit boolean
+    T_64PBOOL64=0x0633,   // 64 bit pointer to 64 bit boolean
+  };
+
+  //  No leaf index can have a value of 0x0000.  The leaf indices are
+  //  separated into ranges depending upon the use of the type record.
+  //  The second range is for the type records that are directly referenced
+  //  in symbols. The first range is for type records that are not
+  //  referenced by symbols but instead are referenced by other type
+  //  records.  All type records must have a starting leaf index in these
+  //  first two ranges.  The third range of leaf indices are used to build
+  //  up complex lists such as the field list of a class type record.  No
+  //  type record can begin with one of the leaf indices. The fourth ranges
+  //  of type indices are used to represent numeric data in a symbol or
+  //  type record. These leaf indices are greater than 0x8000.  At the
+  //  point that type or symbol processor is expecting a numeric field, the
+  //  next two bytes in the type record are examined.  If the value is less
+  //  than 0x8000, then the two bytes contain the numeric value.  If the
+  //  value is greater than 0x8000, then the data follows the leaf index in
+  //  a format specified by the leaf index. The final range of leaf indices
+  //  are used to force alignment of subfields within a complex type record..
+  //
+
+  internal enum LEAF {
+    // leaf indices starting records but referenced from symbol records
+
+    LF_VTSHAPE=0x000a,
+    LF_COBOL1=0x000c,
+    LF_LABEL=0x000e,
+    LF_NULL=0x000f,
+    LF_NOTTRAN=0x0010,
+    LF_ENDPRECOMP=0x0014,       // not referenced from symbol
+    LF_TYPESERVER_ST=0x0016,       // not referenced from symbol
+
+    // leaf indices starting records but referenced only from type records
+
+    LF_LIST=0x0203,
+    LF_REFSYM=0x020c,
+
+    LF_ENUMERATE_ST=0x0403,
+
+    // 32-bit type index versions of leaves, all have the 0x1000 bit set
+    //
+    LF_TI16_MAX=0x1000,
+
+    LF_MODIFIER=0x1001,
+    LF_POINTER=0x1002,
+    LF_ARRAY_ST=0x1003,
+    LF_CLASS_ST=0x1004,
+    LF_STRUCTURE_ST=0x1005,
+    LF_UNION_ST=0x1006,
+    LF_ENUM_ST=0x1007,
+    LF_PROCEDURE=0x1008,
+    LF_MFUNCTION=0x1009,
+    LF_COBOL0=0x100a,
+    LF_BARRAY=0x100b,
+    LF_DIMARRAY_ST=0x100c,
+    LF_VFTPATH=0x100d,
+    LF_PRECOMP_ST=0x100e,       // not referenced from symbol
+    LF_OEM=0x100f,       // oem definable type string
+    LF_ALIAS_ST=0x1010,       // alias (typedef) type
+    LF_OEM2=0x1011,       // oem definable type string
+
+    // leaf indices starting records but referenced only from type records
+
+    LF_SKIP=0x1200,
+    LF_ARGLIST=0x1201,
+    LF_DEFARG_ST=0x1202,
+    LF_FIELDLIST=0x1203,
+    LF_DERIVED=0x1204,
+    LF_BITFIELD=0x1205,
+    LF_METHODLIST=0x1206,
+    LF_DIMCONU=0x1207,
+    LF_DIMCONLU=0x1208,
+    LF_DIMVARU=0x1209,
+    LF_DIMVARLU=0x120a,
+
+    LF_BCLASS=0x1400,
+    LF_VBCLASS=0x1401,
+    LF_IVBCLASS=0x1402,
+    LF_FRIENDFCN_ST=0x1403,
+    LF_INDEX=0x1404,
+    LF_MEMBER_ST=0x1405,
+    LF_STMEMBER_ST=0x1406,
+    LF_METHOD_ST=0x1407,
+    LF_NESTTYPE_ST=0x1408,
+    LF_VFUNCTAB=0x1409,
+    LF_FRIENDCLS=0x140a,
+    LF_ONEMETHOD_ST=0x140b,
+    LF_VFUNCOFF=0x140c,
+    LF_NESTTYPEEX_ST=0x140d,
+    LF_MEMBERMODIFY_ST=0x140e,
+    LF_MANAGED_ST=0x140f,
+
+    // Types w/ SZ names
+
+    LF_ST_MAX=0x1500,
+
+    LF_TYPESERVER=0x1501,       // not referenced from symbol
+    LF_ENUMERATE=0x1502,
+    LF_ARRAY=0x1503,
+    LF_CLASS=0x1504,
+    LF_STRUCTURE=0x1505,
+    LF_UNION=0x1506,
+    LF_ENUM=0x1507,
+    LF_DIMARRAY=0x1508,
+    LF_PRECOMP=0x1509,       // not referenced from symbol
+    LF_ALIAS=0x150a,       // alias (typedef) type
+    LF_DEFARG=0x150b,
+    LF_FRIENDFCN=0x150c,
+    LF_MEMBER=0x150d,
+    LF_STMEMBER=0x150e,
+    LF_METHOD=0x150f,
+    LF_NESTTYPE=0x1510,
+    LF_ONEMETHOD=0x1511,
+    LF_NESTTYPEEX=0x1512,
+    LF_MEMBERMODIFY=0x1513,
+    LF_MANAGED=0x1514,
+    LF_TYPESERVER2=0x1515,
+
+    LF_NUMERIC=0x8000,
+    LF_CHAR=0x8000,
+    LF_SHORT=0x8001,
+    LF_USHORT=0x8002,
+    LF_LONG=0x8003,
+    LF_ULONG=0x8004,
+    LF_REAL32=0x8005,
+    LF_REAL64=0x8006,
+    LF_REAL80=0x8007,
+    LF_REAL128=0x8008,
+    LF_QUADWORD=0x8009,
+    LF_UQUADWORD=0x800a,
+    LF_COMPLEX32=0x800c,
+    LF_COMPLEX64=0x800d,
+    LF_COMPLEX80=0x800e,
+    LF_COMPLEX128=0x800f,
+    LF_VARSTRING=0x8010,
+
+    LF_OCTWORD=0x8017,
+    LF_UOCTWORD=0x8018,
+
+    LF_DECIMAL=0x8019,
+    LF_DATE=0x801a,
+    LF_UTF8STRING=0x801b,
+
+    LF_PAD0=0xf0,
+    LF_PAD1=0xf1,
+    LF_PAD2=0xf2,
+    LF_PAD3=0xf3,
+    LF_PAD4=0xf4,
+    LF_PAD5=0xf5,
+    LF_PAD6=0xf6,
+    LF_PAD7=0xf7,
+    LF_PAD8=0xf8,
+    LF_PAD9=0xf9,
+    LF_PAD10=0xfa,
+    LF_PAD11=0xfb,
+    LF_PAD12=0xfc,
+    LF_PAD13=0xfd,
+    LF_PAD14=0xfe,
+    LF_PAD15=0xff,
+
+  };
+
+  // end of leaf indices
+
+  //  Type enum for pointer records
+  //  Pointers can be one of the following types
+
+  internal enum CV_ptrtype {
+    CV_PTR_BASE_SEG=0x03, // based on segment
+    CV_PTR_BASE_VAL=0x04, // based on value of base
+    CV_PTR_BASE_SEGVAL=0x05, // based on segment value of base
+    CV_PTR_BASE_ADDR=0x06, // based on address of base
+    CV_PTR_BASE_SEGADDR=0x07, // based on segment address of base
+    CV_PTR_BASE_TYPE=0x08, // based on type
+    CV_PTR_BASE_SELF=0x09, // based on self
+    CV_PTR_NEAR32=0x0a, // 32 bit pointer
+    CV_PTR_64=0x0c, // 64 bit pointer
+    CV_PTR_UNUSEDPTR=0x0d  // first unused pointer type
+  };
+
+  //  Mode enum for pointers
+  //  Pointers can have one of the following modes
+
+  internal enum CV_ptrmode {
+    CV_PTR_MODE_PTR=0x00, // "normal" pointer
+    CV_PTR_MODE_REF=0x01, // reference
+    CV_PTR_MODE_PMEM=0x02, // pointer to data member
+    CV_PTR_MODE_PMFUNC=0x03, // pointer to member function
+    CV_PTR_MODE_RESERVED=0x04  // first unused pointer mode
+  };
+
+  //  enumeration for pointer-to-member types
+
+  internal enum CV_pmtype {
+    CV_PMTYPE_Undef=0x00, // not specified (pre VC8)
+    CV_PMTYPE_D_Single=0x01, // member data, single inheritance
+    CV_PMTYPE_D_Multiple=0x02, // member data, multiple inheritance
+    CV_PMTYPE_D_Virtual=0x03, // member data, virtual inheritance
+    CV_PMTYPE_D_General=0x04, // member data, most general
+    CV_PMTYPE_F_Single=0x05, // member function, single inheritance
+    CV_PMTYPE_F_Multiple=0x06, // member function, multiple inheritance
+    CV_PMTYPE_F_Virtual=0x07, // member function, virtual inheritance
+    CV_PMTYPE_F_General=0x08, // member function, most general
+  };
+
+  //  enumeration for method properties
+
+  internal enum CV_methodprop {
+    CV_MTvanilla=0x00,
+    CV_MTvirtual=0x01,
+    CV_MTstatic=0x02,
+    CV_MTfriend=0x03,
+    CV_MTintro=0x04,
+    CV_MTpurevirt=0x05,
+    CV_MTpureintro=0x06
+  };
+
+  //  enumeration for virtual shape table entries
+
+  internal enum CV_VTS_desc {
+    CV_VTS_near=0x00,
+    CV_VTS_far=0x01,
+    CV_VTS_thin=0x02,
+    CV_VTS_outer=0x03,
+    CV_VTS_meta=0x04,
+    CV_VTS_near32=0x05,
+    CV_VTS_far32=0x06,
+    CV_VTS_unused=0x07
+  };
+
+  //  enumeration for LF_LABEL address modes
+
+  internal enum CV_LABEL_TYPE {
+    CV_LABEL_NEAR=0,       // near return
+    CV_LABEL_FAR=4        // far return
+  };
+
+  //  enumeration for LF_MODIFIER values
+
+  [Flags]
+  internal enum CV_modifier : ushort {
+    MOD_const=0x0001,
+    MOD_volatile=0x0002,
+    MOD_unaligned=0x0004,
+  };
+
+  //  bit field structure describing class/struct/union/enum properties
+
+  [Flags]
+  internal enum CV_prop : ushort {
+    packed=0x0001,   // true if structure is packed
+    ctor=0x0002,   // true if constructors or destructors present
+    ovlops=0x0004,   // true if overloaded operators present
+    isnested=0x0008,   // true if this is a nested class
+    cnested=0x0010,   // true if this class contains nested types
+    opassign=0x0020,   // true if overloaded assignment (=)
+    opcast=0x0040,   // true if casting methods
+    fwdref=0x0080,   // true if forward reference (incomplete defn)
+    scoped=0x0100,   // scoped definition
+  }
+
+  //  class field attribute
+
+  [Flags]
+  internal enum CV_fldattr {
+    access=0x0003,   // access protection CV_access_t
+    mprop=0x001c,   // method properties CV_methodprop_t
+    pseudo=0x0020,   // compiler generated fcn and does not exist
+    noinherit=0x0040,   // true if class cannot be inherited
+    noconstruct=0x0080,   // true if class cannot be constructed
+    compgenx=0x0100,   // compiler generated fcn and does exist
+  }
+
+  //  Structures to access to the type records
+
+  internal struct TYPTYPE {
+    internal ushort len;
+    internal ushort leaf;
+    // byte data[];
+
+    //  char *NextType (char * pType) {
+    //  return (pType + ((TYPTYPE *)pType)->len + sizeof(ushort));
+    //  }
+  };          // general types record
+
+  //  memory representation of pointer to member.  These representations are
+  //  indexed by the enumeration above in the LF_POINTER record
+
+  //  representation of a 32 bit pointer to data for a class with
+  //  or without virtual functions and no virtual bases
+
+  internal struct CV_PDMR32_NVVFCN {
+    internal int mdisp;      // displacement to data (NULL = 0x80000000)
+  };
+
+  //  representation of a 32 bit pointer to data for a class
+  //  with virtual bases
+
+  internal struct CV_PDMR32_VBASE {
+    internal int mdisp;      // displacement to data
+    internal int pdisp;      // this pointer displacement
+    internal int vdisp;      // vbase table displacement
+    // NULL = (,,0xffffffff)
+  };
+
+  //  representation of a 32 bit pointer to member function for a
+  //  class with no virtual bases and a single address point
+
+  internal struct CV_PMFR32_NVSA {
+    internal uint off;        // near address of function (NULL = 0L)
+  };
+
+  //  representation of a 32 bit pointer to member function for a
+  //  class with no virtual bases and multiple address points
+
+  internal struct CV_PMFR32_NVMA {
+    internal uint off;        // near address of function (NULL = 0L,x)
+    internal int disp;
+  };
+
+  //  representation of a 32 bit pointer to member function for a
+  //  class with virtual bases
+
+  internal struct CV_PMFR32_VBASE {
+    internal uint off;        // near address of function (NULL = 0L,x,x,x)
+    internal int mdisp;      // displacement to data
+    internal int pdisp;      // this pointer displacement
+    internal int vdisp;      // vbase table displacement
+  };
+
+  //////////////////////////////////////////////////////////////////////////////
+  //
+  //  The following type records are basically variant records of the
+  //  above structure.  The "ushort leaf" of the above structure and
+  //  the "ushort leaf" of the following type definitions are the same
+  //  symbol.
+  //
+
+  //  Notes on alignment
+  //  Alignment of the fields in most of the type records is done on the
+  //  basis of the TYPTYPE record base.  That is why in most of the lf*
+  //  records that the type is located on what appears to
+  //  be a offset mod 4 == 2 boundary.  The exception to this rule are those
+  //  records that are in a list (lfFieldList, lfMethodList), which are
+  //  aligned to their own bases since they don't have the length field
+  //
+
+  //  Type record for LF_MODIFIER
+
+  internal struct LeafModifier {
+    // internal ushort leaf;      // LF_MODIFIER [TYPTYPE]
+    internal uint type;       // (type index) modified type
+    internal CV_modifier attr;    // modifier attribute modifier_t
+  };
+
+  //  type record for LF_POINTER
+
+  [Flags]
+  internal enum LeafPointerAttr : uint {
+    ptrtype=0x0000001f,   // ordinal specifying pointer type (CV_ptrtype)
+    ptrmode=0x000000e0,   // ordinal specifying pointer mode (CV_ptrmode)
+    isflat32=0x00000100,   // true if 0:32 pointer
+    isvolatile=0x00000200,   // TRUE if volatile pointer
+    isconst=0x00000400,   // TRUE if const pointer
+    isunaligned=0x00000800,   // TRUE if unaligned pointer
+    isrestrict=0x00001000,   // TRUE if restricted pointer (allow agressive opts)
+  };
+
+  internal struct LeafPointer {
+    internal struct LeafPointerBody {
+      // internal ushort leaf;  // LF_POINTER [TYPTYPE]
+      internal uint utype;  // (type index) type index of the underlying type
+      internal LeafPointerAttr attr;
+    };
+#if false
+        union {
+            internal struct {
+                uint    pmclass;    // (type index) index of containing class for pointer to member
+                ushort  pmenum;     // enumeration specifying pm format (CV_pmtype)
+            };
+            ushort  bseg;           // base segment if PTR_BASE_SEG
+            byte[]  Sym;            // copy of base symbol record (including length)
+            internal struct  {
+                uint    index;      // (type index) type index if CV_PTR_BASE_TYPE
+                string  name;       // name of base type
+            } btype;
+        } pbase;
+#endif
+  }
+
+  //  type record for LF_ARRAY
+
+  internal struct LeafArray {
+    // internal ushort leaf;      // LF_ARRAY [TYPTYPE]
+    internal uint elemtype;   // (type index) type index of element type
+    internal uint idxtype;    // (type index) type index of indexing type
+    internal byte[] data;       // variable length data specifying size in bytes
+    internal string name;
+  };
+
+  //  type record for LF_CLASS, LF_STRUCTURE
+
+  internal struct LeafClass {
+    // internal ushort leaf;      // LF_CLASS, LF_STRUCT [TYPTYPE]
+    internal ushort count;      // count of number of elements in class
+    internal ushort property;   // (CV_prop_t) property attribute field (prop_t)
+    internal uint field;      // (type index) type index of LF_FIELD descriptor list
+    internal uint derived;    // (type index) type index of derived from list if not zero
+    internal uint vshape;     // (type index) type index of vshape table for this class
+    internal byte[] data;       // data describing length of structure in bytes
+    internal string name;
+  };
+
+  //  type record for LF_UNION
+
+  internal struct LeafUnion {
+    // internal ushort leaf;      // LF_UNION [TYPTYPE]
+    internal ushort count;      // count of number of elements in class
+    internal ushort property;   // (CV_prop_t) property attribute field
+    internal uint field;      // (type index) type index of LF_FIELD descriptor list
+    internal byte[] data;       // variable length data describing length of
+    internal string name;
+  };
+
+  //  type record for LF_ALIAS
+
+  internal struct LeafAlias {
+    // internal ushort leaf;      // LF_ALIAS [TYPTYPE]
+    internal uint utype;      // (type index) underlying type
+    internal string name;       // alias name
+  };
+
+  //  type record for LF_MANAGED
+
+  internal struct LeafManaged {
+    // internal ushort leaf;      // LF_MANAGED [TYPTYPE]
+    internal string name;       // utf8, zero terminated managed type name
+  };
+
+  //  type record for LF_ENUM
+
+  internal struct LeafEnum {
+    // internal ushort leaf;      // LF_ENUM [TYPTYPE]
+    internal ushort count;      // count of number of elements in class
+    internal ushort property;   // (CV_propt_t) property attribute field
+    internal uint utype;      // (type index) underlying type of the enum
+    internal uint field;      // (type index) type index of LF_FIELD descriptor list
+    internal string name;       // length prefixed name of enum
+  };
+
+  //  Type record for LF_PROCEDURE
+
+  internal struct LeafProc {
+    // internal ushort leaf;      // LF_PROCEDURE [TYPTYPE]
+    internal uint rvtype;     // (type index) type index of return value
+    internal byte calltype;   // calling convention (CV_call_t)
+    internal byte reserved;   // reserved for future use
+    internal ushort parmcount;  // number of parameters
+    internal uint arglist;    // (type index) type index of argument list
+  };
+
+  //  Type record for member function
+
+  internal struct LeafMFunc {
+    // internal ushort leaf;      // LF_MFUNCTION [TYPTYPE]
+    internal uint rvtype;     // (type index) type index of return value
+    internal uint classtype;  // (type index) type index of containing class
+    internal uint thistype;   // (type index) type index of this pointer (model specific)
+    internal byte calltype;   // calling convention (call_t)
+    internal byte reserved;   // reserved for future use
+    internal ushort parmcount;  // number of parameters
+    internal uint arglist;    // (type index) type index of argument list
+    internal int thisadjust; // this adjuster (long because pad required anyway)
+  };
+
+  //  type record for virtual function table shape
+
+  internal struct LeafVTShape {
+    // internal ushort leaf;      // LF_VTSHAPE [TYPTYPE]
+    internal ushort count;      // number of entries in vfunctable
+    internal byte[] desc;       // 4 bit (CV_VTS_desc) descriptors
+  };
+
+  //  type record for cobol0
+
+  internal struct LeafCobol0 {
+    // internal ushort leaf;      // LF_COBOL0 [TYPTYPE]
+    internal uint type;       // (type index) parent type record index
+    internal byte[] data;
+  };
+
+  //  type record for cobol1
+
+  internal struct LeafCobol1 {
+    // internal ushort leaf;      // LF_COBOL1 [TYPTYPE]
+    internal byte[] data;
+  };
+
+  //  type record for basic array
+
+  internal struct LeafBArray {
+    // internal ushort leaf;      // LF_BARRAY [TYPTYPE]
+    internal uint utype;      // (type index) type index of underlying type
+  };
+
+  //  type record for assembler labels
+
+  internal struct LeafLabel {
+    // internal ushort leaf;      // LF_LABEL [TYPTYPE]
+    internal ushort mode;       // addressing mode of label
+  };
+
+  //  type record for dimensioned arrays
+
+  internal struct LeafDimArray {
+    // internal ushort leaf;      // LF_DIMARRAY [TYPTYPE]
+    internal uint utype;      // (type index) underlying type of the array
+    internal uint diminfo;    // (type index) dimension information
+    internal string name;       // length prefixed name
+  };
+
+  //  type record describing path to virtual function table
+
+  internal struct LeafVFTPath {
+    // internal ushort leaf;      // LF_VFTPATH [TYPTYPE]
+    internal uint count;      // count of number of bases in path
+    internal uint[] bases;      // (type index) bases from root to leaf
+  };
+
+  //  type record describing inclusion of precompiled types
+
+  internal struct LeafPreComp {
+    // internal ushort leaf;      // LF_PRECOMP [TYPTYPE]
+    internal uint start;      // starting type index included
+    internal uint count;      // number of types in inclusion
+    internal uint signature;  // signature
+    internal string name;       // length prefixed name of included type file
+  };
+
+  //  type record describing end of precompiled types that can be
+  //  included by another file
+
+  internal struct LeafEndPreComp {
+    // internal ushort leaf;      // LF_ENDPRECOMP [TYPTYPE]
+    internal uint signature;  // signature
+  };
+
+  //  type record for OEM definable type strings
+
+  internal struct LeafOEM {
+    // internal ushort leaf;      // LF_OEM [TYPTYPE]
+    internal ushort cvOEM;      // MS assigned OEM identified
+    internal ushort recOEM;     // OEM assigned type identifier
+    internal uint count;      // count of type indices to follow
+    internal uint[] index;      // (type index) array of type indices followed
+    // by OEM defined data
+  };
+
+  internal enum OEM_ID {
+    OEM_MS_FORTRAN90=0xF090,
+    OEM_ODI=0x0010,
+    OEM_THOMSON_SOFTWARE=0x5453,
+    OEM_ODI_REC_BASELIST=0x0000,
+  };
+
+  internal struct LeafOEM2 {
+    // internal ushort leaf;      // LF_OEM2 [TYPTYPE]
+    internal Guid idOem;      // an oem ID (Guid)
+    internal uint count;      // count of type indices to follow
+    internal uint[] index;      // (type index) array of type indices followed
+    // by OEM defined data
+  };
+
+  //  type record describing using of a type server
+
+  internal struct LeafTypeServer {
+    // internal ushort leaf;      // LF_TYPESERVER [TYPTYPE]
+    internal uint signature;  // signature
+    internal uint age;        // age of database used by this module
+    internal string name;       // length prefixed name of PDB
+  };
+
+  //  type record describing using of a type server with v7 (GUID) signatures
+
+  internal struct LeafTypeServer2 {
+    // internal ushort leaf;      // LF_TYPESERVER2 [TYPTYPE]
+    internal Guid sig70;      // guid signature
+    internal uint age;        // age of database used by this module
+    internal string name;       // length prefixed name of PDB
+  };
+
+  //  description of type records that can be referenced from
+  //  type records referenced by symbols
+
+  //  type record for skip record
+
+  internal struct LeafSkip {
+    // internal ushort leaf;      // LF_SKIP [TYPTYPE]
+    internal uint type;       // (type index) next valid index
+    internal byte[] data;       // pad data
+  };
+
+  //  argument list leaf
+
+  internal struct LeafArgList {
+    // internal ushort leaf;      // LF_ARGLIST [TYPTYPE]
+    internal uint count;      // number of arguments
+    internal uint[] arg;        // (type index) number of arguments
+  };
+
+  //  derived class list leaf
+
+  internal struct LeafDerived {
+    // internal ushort leaf;      // LF_DERIVED [TYPTYPE]
+    internal uint count;      // number of arguments
+    internal uint[] drvdcls;    // (type index) type indices of derived classes
+  };
+
+  //  leaf for default arguments
+
+  internal struct LeafDefArg {
+    // internal ushort leaf;      // LF_DEFARG [TYPTYPE]
+    internal uint type;       // (type index) type of resulting expression
+    internal byte[] expr;       // length prefixed expression string
+  };
+
+  //  list leaf
+  //      This list should no longer be used because the utilities cannot
+  //      verify the contents of the list without knowing what type of list
+  //      it is.  New specific leaf indices should be used instead.
+
+  internal struct LeafList {
+    // internal ushort leaf;      // LF_LIST [TYPTYPE]
+    internal byte[] data;       // data format specified by indexing type
+  };
+
+  //  field list leaf
+  //  This is the header leaf for a complex list of class and structure
+  //  subfields.
+
+  internal struct LeafFieldList {
+    // internal ushort leaf;      // LF_FIELDLIST [TYPTYPE]
+    internal char[] data;       // field list sub lists
+  };
+
+  //  type record for non-static methods and friends in overloaded method list
+
+  internal struct mlMethod {
+    internal ushort attr;       // (CV_fldattr_t) method attribute
+    internal ushort pad0;       // internal padding, must be 0
+    internal uint index;      // (type index) index to type record for procedure
+    internal uint[] vbaseoff;   // offset in vfunctable if intro virtual
+  };
+
+  internal struct LeafMethodList {
+    // internal ushort leaf;      // LF_METHODLIST [TYPTYPE]
+    internal byte[] mList;      // really a mlMethod type
+  };
+
+  //  type record for LF_BITFIELD
+
+  internal struct LeafBitfield {
+    // internal ushort leaf;      // LF_BITFIELD [TYPTYPE]
+    internal uint type;       // (type index) type of bitfield
+    internal byte length;
+    internal byte position;
+  };
+
+  //  type record for dimensioned array with constant bounds
+
+  internal struct LeafDimCon {
+    // internal ushort leaf;      // LF_DIMCONU or LF_DIMCONLU [TYPTYPE]
+    internal uint typ;        // (type index) type of index
+    internal ushort rank;       // number of dimensions
+    internal byte[] dim;        // array of dimension information with
+    // either upper bounds or lower/upper bound
+  };
+
+  //  type record for dimensioned array with variable bounds
+
+  internal struct LeafDimVar {
+    // internal ushort leaf;      // LF_DIMVARU or LF_DIMVARLU [TYPTYPE]
+    internal uint rank;       // number of dimensions
+    internal uint typ;        // (type index) type of index
+    internal uint[] dim;        // (type index) array of type indices for either
+    // variable upper bound or variable
+    // lower/upper bound.  The count of type
+    // indices is rank or rank*2 depending on
+    // whether it is LFDIMVARU or LF_DIMVARLU.
+    // The referenced types must be
+    // LF_REFSYM or T_VOID
+  };
+
+  //  type record for referenced symbol
+
+  internal struct LeafRefSym {
+    // internal ushort leaf;      // LF_REFSYM [TYPTYPE]
+    internal byte[] Sym;        // copy of referenced symbol record
+    // (including length)
+  };
+
+  //  the following are numeric leaves.  They are used to indicate the
+  //  size of the following variable length data.  When the numeric
+  //  data is a single byte less than 0x8000, then the data is output
+  //  directly.  If the data is more the 0x8000 or is a negative value,
+  //  then the data is preceeded by the proper index.
+  //
+
+  //  signed character leaf
+
+  internal struct LeafChar {
+    // internal ushort leaf;      // LF_CHAR [TYPTYPE]
+    internal sbyte val;        // signed 8-bit value
+  };
+
+  //  signed short leaf
+
+  internal struct LeafShort {
+    // internal ushort leaf;      // LF_SHORT [TYPTYPE]
+    internal short val;        // signed 16-bit value
+  };
+
+  //  ushort leaf
+
+  internal struct LeafUShort {
+    // internal ushort leaf;      // LF_ushort [TYPTYPE]
+    internal ushort val;        // unsigned 16-bit value
+  };
+
+  //  signed (32-bit) long leaf
+
+  internal struct LeafLong {
+    // internal ushort leaf;      // LF_LONG [TYPTYPE]
+    internal int val;        // signed 32-bit value
+  };
+
+  //  uint    leaf
+
+  internal struct LeafULong {
+    // internal ushort leaf;      // LF_ULONG [TYPTYPE]
+    internal uint val;        // unsigned 32-bit value
+  };
+
+  //  signed quad leaf
+
+  internal struct LeafQuad {
+    // internal ushort leaf;      // LF_QUAD [TYPTYPE]
+    internal long val;        // signed 64-bit value
+  };
+
+  //  unsigned quad leaf
+
+  internal struct LeafUQuad {
+    // internal ushort leaf;      // LF_UQUAD [TYPTYPE]
+    internal ulong val;        // unsigned 64-bit value
+  };
+
+  //  signed int128 leaf
+
+  internal struct LeafOct {
+    // internal ushort leaf;      // LF_OCT [TYPTYPE]
+    internal ulong val0;
+    internal ulong val1;       // signed 128-bit value
+  };
+
+  //  unsigned int128 leaf
+
+  internal struct LeafUOct {
+    // internal ushort leaf;      // LF_UOCT [TYPTYPE]
+    internal ulong val0;
+    internal ulong val1;       // unsigned 128-bit value
+  };
+
+  //  real 32-bit leaf
+
+  internal struct LeafReal32 {
+    // internal ushort leaf;      // LF_REAL32 [TYPTYPE]
+    internal float val;        // 32-bit real value
+  };
+
+  //  real 64-bit leaf
+
+  internal struct LeafReal64 {
+    // internal ushort leaf;      // LF_REAL64 [TYPTYPE]
+    internal double val;        // 64-bit real value
+  };
+
+  //  real 80-bit leaf
+
+  internal struct LeafReal80 {
+    // internal ushort leaf;      // LF_REAL80 [TYPTYPE]
+    internal FLOAT10 val;        // real 80-bit value
+  };
+
+  //  real 128-bit leaf
+
+  internal struct LeafReal128 {
+    // internal ushort leaf;      // LF_REAL128 [TYPTYPE]
+    internal ulong val0;
+    internal ulong val1;       // real 128-bit value
+  };
+
+  //  complex 32-bit leaf
+
+  internal struct LeafCmplx32 {
+    // internal ushort leaf;      // LF_COMPLEX32 [TYPTYPE]
+    internal float val_real;   // real component
+    internal float val_imag;   // imaginary component
+  };
+
+  //  complex 64-bit leaf
+
+  internal struct LeafCmplx64 {
+    // internal ushort leaf;      // LF_COMPLEX64 [TYPTYPE]
+    internal double val_real;   // real component
+    internal double val_imag;   // imaginary component
+  };
+
+  //  complex 80-bit leaf
+
+  internal struct LeafCmplx80 {
+    // internal ushort leaf;      // LF_COMPLEX80 [TYPTYPE]
+    internal FLOAT10 val_real;   // real component
+    internal FLOAT10 val_imag;   // imaginary component
+  };
+
+  //  complex 128-bit leaf
+
+  internal struct LeafCmplx128 {
+    // internal ushort leaf;      // LF_COMPLEX128 [TYPTYPE]
+    internal ulong val0_real;
+    internal ulong val1_real;  // real component
+    internal ulong val0_imag;
+    internal ulong val1_imag;  // imaginary component
+  };
+
+  //  variable length numeric field
+
+  internal struct LeafVarString {
+    // internal ushort leaf;      // LF_VARSTRING [TYPTYPE]
+    internal ushort len;        // length of value in bytes
+    internal byte[] value;      // value
+  };
+
+  //  index leaf - contains type index of another leaf
+  //  a major use of this leaf is to allow the compilers to emit a
+  //  long complex list (LF_FIELD) in smaller pieces.
+
+  internal struct LeafIndex {
+    // internal ushort leaf;      // LF_INDEX [TYPTYPE]
+    internal ushort pad0;       // internal padding, must be 0
+    internal uint index;      // (type index) type index of referenced leaf
+  };
+
+  //  subfield record for base class field
+
+  internal struct LeafBClass {
+    // internal ushort leaf;      // LF_BCLASS [TYPTYPE]
+    internal ushort attr;       // (CV_fldattr_t) attribute
+    internal uint index;      // (type index) type index of base class
+    internal byte[] offset;     // variable length offset of base within class
+  };
+
+  //  subfield record for direct and indirect virtual base class field
+
+  internal struct LeafVBClass {
+    // internal ushort leaf;      // LF_VBCLASS | LV_IVBCLASS [TYPTYPE]
+    internal ushort attr;       // (CV_fldattr_t) attribute
+    internal uint index;      // (type index) type index of direct virtual base class
+    internal uint vbptr;      // (type index) type index of virtual base pointer
+    internal byte[] vbpoff;     // virtual base pointer offset from address point
+    // followed by virtual base offset from vbtable
+  };
+
+  //  subfield record for friend class
+
+  internal struct LeafFriendCls {
+    // internal ushort leaf;      // LF_FRIENDCLS [TYPTYPE]
+    internal ushort pad0;       // internal padding, must be 0
+    internal uint index;      // (type index) index to type record of friend class
+  };
+
+  //  subfield record for friend function
+
+  internal struct LeafFriendFcn {
+    // internal ushort leaf;      // LF_FRIENDFCN [TYPTYPE]
+    internal ushort pad0;       // internal padding, must be 0
+    internal uint index;      // (type index) index to type record of friend function
+    internal string name;       // name of friend function
+  };
+
+  //  subfield record for non-static data members
+
+  internal struct LeafMember {
+    // internal ushort leaf;      // LF_MEMBER [TYPTYPE]
+    internal ushort attr;       // (CV_fldattr_t)attribute mask
+    internal uint index;      // (type index) index of type record for field
+    internal byte[] offset;     // variable length offset of field
+    internal string name;       // length prefixed name of field
+  };
+
+  //  type record for static data members
+
+  internal struct LeafSTMember {
+    // internal ushort leaf;      // LF_STMEMBER [TYPTYPE]
+    internal ushort attr;       // (CV_fldattr_t) attribute mask
+    internal uint index;      // (type index) index of type record for field
+    internal string name;       // length prefixed name of field
+  };
+
+  //  subfield record for virtual function table pointer
+
+  internal struct LeafVFuncTab {
+    // internal ushort leaf;      // LF_VFUNCTAB [TYPTYPE]
+    internal ushort pad0;       // internal padding, must be 0
+    internal uint type;       // (type index) type index of pointer
+  };
+
+  //  subfield record for virtual function table pointer with offset
+
+  internal struct LeafVFuncOff {
+    // internal ushort leaf;      // LF_VFUNCOFF [TYPTYPE]
+    internal ushort pad0;       // internal padding, must be 0.
+    internal uint type;       // (type index) type index of pointer
+    internal int offset;     // offset of virtual function table pointer
+  };
+
+  //  subfield record for overloaded method list
+
+  internal struct LeafMethod {
+    // internal ushort leaf;      // LF_METHOD [TYPTYPE]
+    internal ushort count;      // number of occurrences of function
+    internal uint mList;      // (type index) index to LF_METHODLIST record
+    internal string name;       // length prefixed name of method
+  };
+
+  //  subfield record for nonoverloaded method
+
+  internal struct LeafOneMethod {
+    // internal ushort leaf;      // LF_ONEMETHOD [TYPTYPE]
+    internal ushort attr;       // (CV_fldattr_t) method attribute
+    internal uint index;      // (type index) index to type record for procedure
+    internal uint[] vbaseoff;   // offset in vfunctable if intro virtual
+    internal string name;
+  };
+
+  //  subfield record for enumerate
+
+  internal struct LeafEnumerate {
+    // internal ushort leaf;      // LF_ENUMERATE [TYPTYPE]
+    internal ushort attr;       // (CV_fldattr_t) access
+    internal byte[] value;      // variable length value field
+    internal string name;
+  };
+
+  //  type record for nested (scoped) type definition
+
+  internal struct LeafNestType {
+    // internal ushort leaf;      // LF_NESTTYPE [TYPTYPE]
+    internal ushort pad0;       // internal padding, must be 0
+    internal uint index;      // (type index) index of nested type definition
+    internal string name;       // length prefixed type name
+  };
+
+  //  type record for nested (scoped) type definition, with attributes
+  //  new records for vC v5.0, no need to have 16-bit ti versions.
+
+  internal struct LeafNestTypeEx {
+    // internal ushort leaf;      // LF_NESTTYPEEX [TYPTYPE]
+    internal ushort attr;       // (CV_fldattr_t) member access
+    internal uint index;      // (type index) index of nested type definition
+    internal string name;       // length prefixed type name
+  };
+
+  //  type record for modifications to members
+
+  internal struct LeafMemberModify {
+    // internal ushort leaf;      // LF_MEMBERMODIFY [TYPTYPE]
+    internal ushort attr;       // (CV_fldattr_t) the new attributes
+    internal uint index;      // (type index) index of base class type definition
+    internal string name;       // length prefixed member name
+  };
+
+  //  type record for pad leaf
+
+  internal struct LeafPad {
+    internal byte leaf;
+  };
+
+  //  Symbol definitions
+
+  internal enum SYM {
+    S_END=0x0006,  // Block, procedure, "with" or thunk end
+    S_OEM=0x0404,  // OEM defined symbol
+
+    S_REGISTER_ST=0x1001,  // Register variable
+    S_CONSTANT_ST=0x1002,  // constant symbol
+    S_UDT_ST=0x1003,  // User defined type
+    S_COBOLUDT_ST=0x1004,  // special UDT for cobol that does not symbol pack
+    S_MANYREG_ST=0x1005,  // multiple register variable
+    S_BPREL32_ST=0x1006,  // BP-relative
+    S_LDATA32_ST=0x1007,  // Module-local symbol
+    S_GDATA32_ST=0x1008,  // Global data symbol
+    S_PUB32_ST=0x1009,  // a internal symbol (CV internal reserved)
+    S_LPROC32_ST=0x100a,  // Local procedure start
+    S_GPROC32_ST=0x100b,  // Global procedure start
+    S_VFTABLE32=0x100c,  // address of virtual function table
+    S_REGREL32_ST=0x100d,  // register relative address
+    S_LTHREAD32_ST=0x100e,  // local thread storage
+    S_GTHREAD32_ST=0x100f,  // global thread storage
+
+    S_LPROCMIPS_ST=0x1010,  // Local procedure start
+    S_GPROCMIPS_ST=0x1011,  // Global procedure start
+
+    // new symbol records for edit and continue information
+
+    S_FRAMEPROC=0x1012,  // extra frame and proc information
+    S_COMPILE2_ST=0x1013,  // extended compile flags and info
+
+    // new symbols necessary for 16-bit enumerates of IA64 registers
+    // and IA64 specific symbols
+
+    S_MANYREG2_ST=0x1014,  // multiple register variable
+    S_LPROCIA64_ST=0x1015,  // Local procedure start (IA64)
+    S_GPROCIA64_ST=0x1016,  // Global procedure start (IA64)
+
+    // Local symbols for IL
+    S_LOCALSLOT_ST=0x1017,  // local IL sym with field for local slot index
+    S_PARAMSLOT_ST=0x1018,  // local IL sym with field for parameter slot index
+
+    S_ANNOTATION=0x1019,  // Annotation string literals
+
+    // symbols to support managed code debugging
+    S_GMANPROC_ST=0x101a,  // Global proc
+    S_LMANPROC_ST=0x101b,  // Local proc
+    S_RESERVED1=0x101c,  // reserved
+    S_RESERVED2=0x101d,  // reserved
+    S_RESERVED3=0x101e,  // reserved
+    S_RESERVED4=0x101f,  // reserved
+    S_LMANDATA_ST=0x1020,
+    S_GMANDATA_ST=0x1021,
+    S_MANFRAMEREL_ST=0x1022,
+    S_MANREGISTER_ST=0x1023,
+    S_MANSLOT_ST=0x1024,
+    S_MANMANYREG_ST=0x1025,
+    S_MANREGREL_ST=0x1026,
+    S_MANMANYREG2_ST=0x1027,
+    S_MANTYPREF=0x1028,  // Index for type referenced by name from metadata
+    S_UNAMESPACE_ST=0x1029,  // Using namespace
+
+    // Symbols w/ SZ name fields. All name fields contain utf8 encoded strings.
+    S_ST_MAX=0x1100,  // starting point for SZ name symbols
+
+    S_OBJNAME=0x1101,  // path to object file name
+    S_THUNK32=0x1102,  // Thunk Start
+    S_BLOCK32=0x1103,  // block start
+    S_WITH32=0x1104,  // with start
+    S_LABEL32=0x1105,  // code label
+    S_REGISTER=0x1106,  // Register variable
+    S_CONSTANT=0x1107,  // constant symbol
+    S_UDT=0x1108,  // User defined type
+    S_COBOLUDT=0x1109,  // special UDT for cobol that does not symbol pack
+    S_MANYREG=0x110a,  // multiple register variable
+    S_BPREL32=0x110b,  // BP-relative
+    S_LDATA32=0x110c,  // Module-local symbol
+    S_GDATA32=0x110d,  // Global data symbol
+    S_PUB32=0x110e,  // a internal symbol (CV internal reserved)
+    S_LPROC32=0x110f,  // Local procedure start
+    S_GPROC32=0x1110,  // Global procedure start
+    S_REGREL32=0x1111,  // register relative address
+    S_LTHREAD32=0x1112,  // local thread storage
+    S_GTHREAD32=0x1113,  // global thread storage
+
+    S_LPROCMIPS=0x1114,  // Local procedure start
+    S_GPROCMIPS=0x1115,  // Global procedure start
+    S_COMPILE2=0x1116,  // extended compile flags and info
+    S_MANYREG2=0x1117,  // multiple register variable
+    S_LPROCIA64=0x1118,  // Local procedure start (IA64)
+    S_GPROCIA64=0x1119,  // Global procedure start (IA64)
+    S_LOCALSLOT=0x111a,  // local IL sym with field for local slot index
+    S_SLOT=S_LOCALSLOT,  // alias for LOCALSLOT
+    S_PARAMSLOT=0x111b,  // local IL sym with field for parameter slot index
+
+    // symbols to support managed code debugging
+    S_LMANDATA=0x111c,
+    S_GMANDATA=0x111d,
+    S_MANFRAMEREL=0x111e,
+    S_MANREGISTER=0x111f,
+    S_MANSLOT=0x1120,
+    S_MANMANYREG=0x1121,
+    S_MANREGREL=0x1122,
+    S_MANMANYREG2=0x1123,
+    S_UNAMESPACE=0x1124,  // Using namespace
+
+    // ref symbols with name fields
+    S_PROCREF=0x1125,  // Reference to a procedure
+    S_DATAREF=0x1126,  // Reference to data
+    S_LPROCREF=0x1127,  // Local Reference to a procedure
+    S_ANNOTATIONREF=0x1128,  // Reference to an S_ANNOTATION symbol
+    S_TOKENREF=0x1129,  // Reference to one of the many MANPROCSYM's
+
+    // continuation of managed symbols
+    S_GMANPROC=0x112a,  // Global proc
+    S_LMANPROC=0x112b,  // Local proc
+
+    // short, light-weight thunks
+    S_TRAMPOLINE=0x112c,  // trampoline thunks
+    S_MANCONSTANT=0x112d,  // constants with metadata type info
+
+    // native attributed local/parms
+    S_ATTR_FRAMEREL=0x112e,  // relative to virtual frame ptr
+    S_ATTR_REGISTER=0x112f,  // stored in a register
+    S_ATTR_REGREL=0x1130,  // relative to register (alternate frame ptr)
+    S_ATTR_MANYREG=0x1131,  // stored in >1 register
+
+    // Separated code (from the compiler) support
+    S_SEPCODE=0x1132,
+
+    S_LOCAL=0x1133,  // defines a local symbol in optimized code
+    S_DEFRANGE=0x1134,  // defines a single range of addresses in which symbol can be evaluated
+    S_DEFRANGE2=0x1135,  // defines ranges of addresses in which symbol can be evaluated
+
+    S_SECTION=0x1136,  // A COFF section in a PE executable
+    S_COFFGROUP=0x1137,  // A COFF group
+    S_EXPORT=0x1138,  // A export
+
+    S_CALLSITEINFO=0x1139,  // Indirect call site information
+    S_FRAMECOOKIE=0x113a,  // Security cookie information
+
+    S_DISCARDED=0x113b,  // Discarded by LINK /OPT:REF (experimental, see richards)
+
+    S_RECTYPE_MAX,              // one greater than last
+    S_RECTYPE_LAST=S_RECTYPE_MAX - 1,
+
+  };
+
+  //  enum describing compile flag ambient data model
+
+  internal enum CV_CFL_DATA {
+    CV_CFL_DNEAR=0x00,
+    CV_CFL_DFAR=0x01,
+    CV_CFL_DHUGE=0x02
+  };
+
+  //  enum describing compile flag ambiant code model
+
+  internal enum CV_CFL_CODE {
+    CV_CFL_CNEAR=0x00,
+    CV_CFL_CFAR=0x01,
+    CV_CFL_CHUGE=0x02
+  };
+
+  //  enum describing compile flag target floating point package
+
+  internal enum CV_CFL_FPKG {
+    CV_CFL_NDP=0x00,
+    CV_CFL_EMU=0x01,
+    CV_CFL_ALT=0x02
+  };
+
+  // enum describing function return method
+
+  [Flags]
+  internal enum CV_PROCFLAGS : byte {
+    CV_PFLAG_NOFPO=0x01, // frame pointer present
+    CV_PFLAG_INT=0x02, // interrupt return
+    CV_PFLAG_FAR=0x04, // far return
+    CV_PFLAG_NEVER=0x08, // function does not return
+    CV_PFLAG_NOTREACHED=0x10, // label isn't fallen into
+    CV_PFLAG_CUST_CALL=0x20, // custom calling convention
+    CV_PFLAG_NOINLINE=0x40, // function marked as noinline
+    CV_PFLAG_OPTDBGINFO=0x80, // function has debug information for optimized code
+  };
+
+  // Extended proc flags
+  //
+  internal struct CV_EXPROCFLAGS {
+    internal byte flags;      // (CV_PROCFLAGS)
+    internal byte reserved;   // must be zero
+  };
+
+  // local variable flags
+  [Flags]
+  internal enum CV_LVARFLAGS : ushort {
+    fIsParam=0x0001,   // variable is a parameter
+    fAddrTaken=0x0002,   // address is taken
+    fCompGenx=0x0004,   // variable is compiler generated
+    fIsAggregate=0x0008,   // the symbol is splitted in temporaries,
+    // which are treated by compiler as
+    // independent entities
+    fIsAggregated=0x0010,   // Counterpart of fIsAggregate - tells
+    // that it is a part of a fIsAggregate symbol
+    fIsAliased=0x0020,   // variable has multiple simultaneous lifetimes
+    fIsAlias=0x0040,   // represents one of the multiple simultaneous lifetimes
+  };
+
+  // represents an address range, used for optimized code debug info
+  internal struct CV_lvar_addr_range {       // defines a range of addresses
+    internal uint offStart;
+    internal ushort isectStart;
+    internal uint cbRange;
+  };
+
+  // enum describing function data return method
+
+  internal enum CV_GENERIC_STYLE {
+    CV_GENERIC_VOID=0x00,   // void return type
+    CV_GENERIC_REG=0x01,   // return data is in registers
+    CV_GENERIC_ICAN=0x02,   // indirect caller allocated near
+    CV_GENERIC_ICAF=0x03,   // indirect caller allocated far
+    CV_GENERIC_IRAN=0x04,   // indirect returnee allocated near
+    CV_GENERIC_IRAF=0x05,   // indirect returnee allocated far
+    CV_GENERIC_UNUSED=0x06    // first unused
+  };
+
+  [Flags]
+  internal enum CV_GENERIC_FLAG : ushort {
+    cstyle=0x0001,       // true push varargs right to left
+    rsclean=0x0002,       // true if returnee stack cleanup
+  };
+
+  // flag bitfields for separated code attributes
+
+  [Flags]
+  internal enum CV_SEPCODEFLAGS : uint {
+    fIsLexicalScope=0x00000001,   // S_SEPCODE doubles as lexical scope
+    fReturnsToParent=0x00000002,   // code frag returns to parent
+  };
+
+  // Generic layout for symbol records
+
+  internal struct SYMTYPE {
+    internal ushort reclen;     // Record length
+    internal ushort rectyp;     // Record type
+    // byte        data[CV_ZEROLEN];
+    //  SYMTYPE *NextSym (SYMTYPE * pSym) {
+    //  return (SYMTYPE *) ((char *)pSym + pSym->reclen + sizeof(ushort));
+    //  }
+  };
+
+  //  non-model specific symbol types
+
+  internal struct RegSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_REGISTER
+    internal uint typind;     // (type index) Type index or Metadata token
+    internal ushort reg;        // register enumerate
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct AttrRegSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_MANREGISTER | S_ATTR_REGISTER
+    internal uint typind;     // (type index) Type index or Metadata token
+    internal uint offCod;     // first code address where var is live
+    internal ushort segCod;
+    internal ushort flags;      // (CV_LVARFLAGS)local var flags
+    internal ushort reg;        // register enumerate
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct ManyRegSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_MANYREG
+    internal uint typind;     // (type index) Type index or metadata token
+    internal byte count;      // count of number of registers
+    internal byte[] reg;        // count register enumerates, most-sig first
+    internal string name;       // length-prefixed name.
+  };
+
+  internal struct ManyRegSym2 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_MANYREG2
+    internal uint typind;     // (type index) Type index or metadata token
+    internal ushort count;      // count of number of registers,
+    internal ushort[] reg;        // count register enumerates, most-sig first
+    internal string name;       // length-prefixed name.
+  };
+
+  internal struct AttrManyRegSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_MANMANYREG
+    internal uint typind;     // (type index) Type index or metadata token
+    internal uint offCod;     // first code address where var is live
+    internal ushort segCod;
+    internal ushort flags;      // (CV_LVARFLAGS)local var flags
+    internal byte count;      // count of number of registers
+    internal byte[] reg;        // count register enumerates, most-sig first
+    internal string name;       // utf-8 encoded zero terminate name
+  };
+
+  internal struct AttrManyRegSym2 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_MANMANYREG2 | S_ATTR_MANYREG
+    internal uint typind;     // (type index) Type index or metadata token
+    internal uint offCod;     // first code address where var is live
+    internal ushort segCod;
+    internal ushort flags;      // (CV_LVARFLAGS)local var flags
+    internal ushort count;      // count of number of registers
+    internal ushort[] reg;        // count register enumerates, most-sig first
+    internal string name;       // utf-8 encoded zero terminate name
+  };
+
+  internal struct ConstSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_CONSTANT or S_MANCONSTANT
+    internal uint typind;     // (type index) Type index (containing enum if enumerate) or metadata token
+    internal ushort value;      // numeric leaf containing value
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct UdtSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_UDT | S_COBOLUDT
+    internal uint typind;     // (type index) Type index
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct ManyTypRef {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_MANTYPREF
+    internal uint typind;     // (type index) Type index
+  };
+
+  internal struct SearchSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_SSEARCH
+    internal uint startsym;   // offset of the procedure
+    internal ushort seg;        // segment of symbol
+  };
+
+  [Flags]
+  internal enum CFLAGSYM_FLAGS : ushort {
+    pcode=0x0001,   // true if pcode present
+    floatprec=0x0006,   // floating precision
+    floatpkg=0x0018,   // float package
+    ambdata=0x00e0,   // ambient data model
+    ambcode=0x0700,   // ambient code model
+    mode32=0x0800,   // true if compiled 32 bit mode
+  };
+
+  internal struct CFlagSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_COMPILE
+    internal byte machine;    // target processor
+    internal byte language;   // language index
+    internal ushort flags;      // (CFLAGSYM_FLAGS)
+    internal string ver;        // Length-prefixed compiler version string
+  };
+
+  [Flags]
+  internal enum COMPILESYM_FLAGS : uint {
+    iLanguage=0x000000ff,   // language index
+    fEC=0x00000100,   // compiled for E/C
+    fNoDbgInfo=0x00000200,   // not compiled with debug info
+    fLTCG=0x00000400,   // compiled with LTCG
+    fNoDataAlign=0x00000800,   // compiled with -Bzalign
+    fManagedPresent=0x00001000,   // managed code/data present
+    fSecurityChecks=0x00002000,   // compiled with /GS
+    fHotPatch=0x00004000,   // compiled with /hotpatch
+    fCVTCIL=0x00008000,   // converted with CVTCIL
+    fMSILModule=0x00010000,   // MSIL netmodule
+  };
+
+  internal struct CompileSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_COMPILE2
+    internal uint flags;      // (COMPILESYM_FLAGS)
+    internal ushort machine;    // target processor
+    internal ushort verFEMajor; // front end major version #
+    internal ushort verFEMinor; // front end minor version #
+    internal ushort verFEBuild; // front end build version #
+    internal ushort verMajor;   // back end major version #
+    internal ushort verMinor;   // back end minor version #
+    internal ushort verBuild;   // back end build version #
+    internal string verSt;      // Length-prefixed compiler version string, followed
+    internal string[] verArgs;    // block of zero terminated strings, ended by double-zero.
+  };
+
+  internal struct ObjNameSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_OBJNAME
+    internal uint signature;  // signature
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct EndArgSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_ENDARG
+  };
+
+  internal struct ReturnSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_RETURN
+    internal CV_GENERIC_FLAG flags; // flags
+    internal byte style;      // CV_GENERIC_STYLE return style
+    // followed by return method data
+  };
+
+  internal struct EntryThisSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_ENTRYTHIS
+    internal byte thissym;    // symbol describing this pointer on entry
+  };
+
+  internal struct BpRelSym32 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_BPREL32
+    internal int off;        // BP-relative offset
+    internal uint typind;     // (type index) Type index or Metadata token
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct FrameRelSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_MANFRAMEREL | S_ATTR_FRAMEREL
+    internal int off;        // Frame relative offset
+    internal uint typind;     // (type index) Type index or Metadata token
+    internal uint offCod;     // first code address where var is live
+    internal ushort segCod;
+    internal ushort flags;      // (CV_LVARFLAGS)local var flags
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct SlotSym32 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_LOCALSLOT or S_PARAMSLOT
+    internal uint index;      // slot index
+    internal uint typind;     // (type index) Type index or Metadata token
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct AttrSlotSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_MANSLOT
+    internal uint index;      // slot index
+    internal uint typind;     // (type index) Type index or Metadata token
+    internal uint offCod;     // first code address where var is live
+    internal ushort segCod;
+    internal ushort flags;      // (CV_LVARFLAGS)local var flags
+    internal string name;       // Length-prefixed name
+
+  };
+
+  internal struct AnnotationSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_ANNOTATION
+    internal uint off;
+    internal ushort seg;
+    internal ushort csz;        // Count of zero terminated annotation strings
+    internal string[] rgsz;       // Sequence of zero terminated annotation strings
+  };
+
+  internal struct DatasSym32 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_LDATA32, S_GDATA32 or S_PUB32, S_LMANDATA, S_GMANDATA
+    internal uint typind;     // (type index) Type index, or Metadata token if a managed symbol
+    internal uint off;
+    internal ushort seg;
+    internal string name;       // Length-prefixed name
+  };
+
+  [Flags]
+  internal enum CV_PUBSYMFLAGS : uint {
+    fNone=0,
+    fCode=0x00000001,     // set if internal symbol refers to a code address
+    fFunction=0x00000002,     // set if internal symbol is a function
+    fManaged=0x00000004,     // set if managed code (native or IL)
+    fMSIL=0x00000008,     // set if managed IL code
+  };
+
+  internal struct PubSym32 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_PUB32
+    internal uint flags;      // (CV_PUBSYMFLAGS)
+    internal uint off;
+    internal ushort seg;
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct ProcSym32 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_GPROC32 or S_LPROC32
+    internal uint parent;     // pointer to the parent
+    internal uint end;        // pointer to this blocks end
+    internal uint next;       // pointer to next symbol
+    internal uint len;        // Proc length
+    internal uint dbgStart;   // Debug start offset
+    internal uint dbgEnd;     // Debug end offset
+    internal uint typind;     // (type index) Type index
+    internal uint off;
+    internal ushort seg;
+    internal byte flags;      // (CV_PROCFLAGS) Proc flags
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct ManProcSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_GMANPROC, S_LMANPROC, S_GMANPROCIA64 or S_LMANPROCIA64
+    internal uint parent;     // pointer to the parent
+    internal uint end;        // pointer to this blocks end
+    internal uint next;       // pointer to next symbol
+    internal uint len;        // Proc length
+    internal uint dbgStart;   // Debug start offset
+    internal uint dbgEnd;     // Debug end offset
+    internal uint token;      // COM+ metadata token for method
+    internal uint off;
+    internal ushort seg;
+    internal byte flags;      // (CV_PROCFLAGS) Proc flags
+    internal ushort retReg;     // Register return value is in (may not be used for all archs)
+    internal string name;       // optional name field
+  };
+
+  internal struct ManProcSymMips {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_GMANPROCMIPS or S_LMANPROCMIPS
+    internal uint parent;     // pointer to the parent
+    internal uint end;        // pointer to this blocks end
+    internal uint next;       // pointer to next symbol
+    internal uint len;        // Proc length
+    internal uint dbgStart;   // Debug start offset
+    internal uint dbgEnd;     // Debug end offset
+    internal uint regSave;    // int register save mask
+    internal uint fpSave;     // fp register save mask
+    internal uint intOff;     // int register save offset
+    internal uint fpOff;      // fp register save offset
+    internal uint token;      // COM+ token type
+    internal uint off;
+    internal ushort seg;
+    internal byte retReg;     // Register return value is in
+    internal byte frameReg;   // Frame pointer register
+    internal string name;       // optional name field
+  };
+
+  internal struct ThunkSym32 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_THUNK32
+    internal uint parent;     // pointer to the parent
+    internal uint end;        // pointer to this blocks end
+    internal uint next;       // pointer to next symbol
+    internal uint off;
+    internal ushort seg;
+    internal ushort len;        // length of thunk
+    internal byte ord;        // THUNK_ORDINAL specifying type of thunk
+    internal string name;       // Length-prefixed name
+    internal byte[] variant;    // variant portion of thunk
+  };
+
+  internal enum TRAMP {             // Trampoline subtype
+    trampIncremental,           // incremental thunks
+    trampBranchIsland,          // Branch island thunks
+  };
+
+  internal struct TrampolineSym {   // Trampoline thunk symbol
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_TRAMPOLINE
+    internal ushort trampType;  // trampoline sym subtype
+    internal ushort cbThunk;    // size of the thunk
+    internal uint offThunk;   // offset of the thunk
+    internal uint offTarget;  // offset of the target of the thunk
+    internal ushort sectThunk;  // section index of the thunk
+    internal ushort sectTarget; // section index of the target of the thunk
+  };
+
+  internal struct LabelSym32 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_LABEL32
+    internal uint off;
+    internal ushort seg;
+    internal byte flags;      // (CV_PROCFLAGS) flags
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct BlockSym32 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_BLOCK32
+    internal uint parent;     // pointer to the parent
+    internal uint end;        // pointer to this blocks end
+    internal uint len;        // Block length
+    internal uint off;        // Offset in code segment
+    internal ushort seg;        // segment of label
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct WithSym32 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_WITH32
+    internal uint parent;     // pointer to the parent
+    internal uint end;        // pointer to this blocks end
+    internal uint len;        // Block length
+    internal uint off;        // Offset in code segment
+    internal ushort seg;        // segment of label
+    internal string expr;       // Length-prefixed expression string
+  };
+
+  internal struct VpathSym32 {
+    // internal ushort reclen;    // record length
+    // internal ushort rectyp;    // S_VFTABLE32
+    internal uint root;       // (type index) type index of the root of path
+    internal uint path;       // (type index) type index of the path record
+    internal uint off;        // offset of virtual function table
+    internal ushort seg;        // segment of virtual function table
+  };
+
+  internal struct RegRel32 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_REGREL32
+    internal uint off;        // offset of symbol
+    internal uint typind;     // (type index) Type index or metadata token
+    internal ushort reg;        // register index for symbol
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct AttrRegRel {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_MANREGREL | S_ATTR_REGREL
+    internal uint off;        // offset of symbol
+    internal uint typind;     // (type index) Type index or metadata token
+    internal ushort reg;        // register index for symbol
+    internal uint offCod;     // first code address where var is live
+    internal ushort segCod;
+    internal ushort flags;      // (CV_LVARFLAGS)local var flags
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct ThreadSym32 {
+    // internal ushort reclen;    // record length
+    // internal ushort rectyp;    // S_LTHREAD32 | S_GTHREAD32
+    internal uint typind;     // (type index) type index
+    internal uint off;        // offset into thread storage
+    internal ushort seg;        // segment of thread storage
+    internal string name;       // length prefixed name
+  };
+
+  internal struct Slink32 {
+    // internal ushort reclen;    // record length
+    // internal ushort rectyp;    // S_SLINK32
+    internal uint framesize;  // frame size of parent procedure
+    internal int off;        // signed offset where the static link was saved relative to the value of reg
+    internal ushort reg;
+  };
+
+  internal struct ProcSymMips {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_GPROCMIPS or S_LPROCMIPS
+    internal uint parent;     // pointer to the parent
+    internal uint end;        // pointer to this blocks end
+    internal uint next;       // pointer to next symbol
+    internal uint len;        // Proc length
+    internal uint dbgStart;   // Debug start offset
+    internal uint dbgEnd;     // Debug end offset
+    internal uint regSave;    // int register save mask
+    internal uint fpSave;     // fp register save mask
+    internal uint intOff;     // int register save offset
+    internal uint fpOff;      // fp register save offset
+    internal uint typind;     // (type index) Type index
+    internal uint off;        // Symbol offset
+    internal ushort seg;        // Symbol segment
+    internal byte retReg;     // Register return value is in
+    internal byte frameReg;   // Frame pointer register
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct ProcSymIa64 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_GPROCIA64 or S_LPROCIA64
+    internal uint parent;     // pointer to the parent
+    internal uint end;        // pointer to this blocks end
+    internal uint next;       // pointer to next symbol
+    internal uint len;        // Proc length
+    internal uint dbgStart;   // Debug start offset
+    internal uint dbgEnd;     // Debug end offset
+    internal uint typind;     // (type index) Type index
+    internal uint off;        // Symbol offset
+    internal ushort seg;        // Symbol segment
+    internal ushort retReg;     // Register return value is in
+    internal byte flags;      // (CV_PROCFLAGS) Proc flags
+    internal string name;       // Length-prefixed name
+  };
+
+  internal struct RefSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_PROCREF_ST, S_DATAREF_ST, or S_LPROCREF_ST
+    internal uint sumName;    // SUC of the name
+    internal uint ibSym;      // Offset of actual symbol in $$Symbols
+    internal ushort imod;       // Module containing the actual symbol
+    internal ushort usFill;     // align this record
+  };
+
+  internal struct RefSym2 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_PROCREF, S_DATAREF, or S_LPROCREF
+    internal uint sumName;    // SUC of the name
+    internal uint ibSym;      // Offset of actual symbol in $$Symbols
+    internal ushort imod;       // Module containing the actual symbol
+    internal string name;       // hidden name made a first class member
+  };
+
+  internal struct AlignSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_ALIGN
+  };
+
+  internal struct OemSymbol {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_OEM
+    internal Guid idOem;      // an oem ID (GUID)
+    internal uint typind;     // (type index) Type index
+    internal byte[] rgl;        // user data, force 4-byte alignment
+  };
+
+  [Flags]
+  internal enum FRAMEPROCSYM_FLAGS : uint {
+    fHasAlloca=0x00000001,   // function uses _alloca()
+    fHasSetJmp=0x00000002,   // function uses setjmp()
+    fHasLongJmp=0x00000004,   // function uses longjmp()
+    fHasInlAsm=0x00000008,   // function uses inline asm
+    fHasEH=0x00000010,   // function has EH states
+    fInlSpec=0x00000020,   // function was speced as inline
+    fHasSEH=0x00000040,   // function has SEH
+    fNaked=0x00000080,   // function is __declspec(naked)
+    fSecurityChecks=0x00000100,   // function has buffer security check introduced by /GS.
+    fAsyncEH=0x00000200,   // function compiled with /EHa
+    fGSNoStackOrdering=0x00000400,   // function has /GS buffer checks, but stack ordering couldn't be done
+    fWasInlined=0x00000800,   // function was inlined within another function
+  };
+
+  internal struct FrameProcSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_FRAMEPROC
+    internal uint cbFrame;    // count of bytes of total frame of procedure
+    internal uint cbPad;      // count of bytes of padding in the frame
+    internal uint offPad;     // offset (rel to frame) to where padding starts
+    internal uint cbSaveRegs; // count of bytes of callee save registers
+    internal uint offExHdlr;  // offset of exception handler
+    internal ushort secExHdlr;  // section id of exception handler
+    internal uint flags;      // (FRAMEPROCSYM_FLAGS)
+  }
+
+  internal struct UnamespaceSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_UNAMESPACE
+    internal string name;       // name
+  };
+
+  internal struct SepCodSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_SEPCODE
+    internal uint parent;     // pointer to the parent
+    internal uint end;        // pointer to this block's end
+    internal uint length;     // count of bytes of this block
+    internal uint scf;        // (CV_SEPCODEFLAGS) flags
+    internal uint off;        // sec:off of the separated code
+    internal uint offParent;  // secParent:offParent of the enclosing scope
+    internal ushort sec;        //  (proc, block, or sepcode)
+    internal ushort secParent;
+  };
+
+  internal struct LocalSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_LOCAL
+    internal uint id;         // id of the local
+    internal uint typind;     // (type index) type index
+    internal ushort flags;      // (CV_LVARFLAGS) local var flags
+    internal uint idParent;   // This is is parent variable - fIsAggregated or fIsAlias
+    internal uint offParent;  // Offset in parent variable - fIsAggregated
+
+    internal uint expr;       // NI of expression that this temp holds
+    internal uint pad0;       // pad, must be zero
+    internal uint pad1;       // pad, must be zero
+
+    internal string name;       // Name of this symbol.
+  }
+
+  internal struct DefRangeSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_DEFRANGE
+
+    internal uint id;         // ID of the local symbol for which this formula holds
+    internal uint program;    // program to evaluate the value of the symbol
+
+    internal CV_lvar_addr_range range;   // Range of addresses where this program is valid
+  };
+
+  internal struct DefRangeSym2 {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_DEFRANGE2
+
+    internal uint id;         // ID of the local symbol for which this formula holds
+    internal uint program;    // program to evaluate the value of the symbol
+
+    internal ushort count;      // count of CV_lvar_addr_range records following
+    internal CV_lvar_addr_range[] range;// Range of addresses where this program is valid
+  };
+
+  internal struct SectionSym {
+    // internal ushort reclen     // Record length
+    // internal ushort rectyp;    // S_SECTION
+
+    internal ushort isec;       // Section number
+    internal byte align;      // Alignment of this section (power of 2)
+    internal byte bReserved;  // Reserved.  Must be zero.
+    internal uint rva;
+    internal uint cb;
+    internal uint characteristics;
+    internal string name;       // name
+  };
+
+  internal struct CoffGroupSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_COFFGROUP
+
+    internal uint cb;
+    internal uint characteristics;
+    internal uint off;        // Symbol offset
+    internal ushort seg;        // Symbol segment
+    internal string name;       // name
+  };
+
+  [Flags]
+  internal enum EXPORTSYM_FLAGS : ushort {
+    fConstant=0x0001,   // CONSTANT
+    fData=0x0002,   // DATA
+    fPrivate=0x0004,   // PRIVATE
+    fNoName=0x0008,   // NONAME
+    fOrdinal=0x0010,   // Ordinal was explicitly assigned
+    fForwarder=0x0020,   // This is a forwarder
+  }
+
+  internal struct ExportSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_EXPORT
+
+    internal ushort ordinal;
+    internal ushort flags;      // (EXPORTSYM_FLAGS)
+    internal string name;       // name of
+  };
+
+  //
+  // Symbol for describing indirect calls when they are using
+  // a function pointer cast on some other type or temporary.
+  // Typical content will be an LF_POINTER to an LF_PROCEDURE
+  // type record that should mimic an actual variable with the
+  // function pointer type in question.
+  //
+  // Since the compiler can sometimes tail-merge a function call
+  // through a function pointer, there may be more than one
+  // S_CALLSITEINFO record at an address.  This is similar to what
+  // you could do in your own code by:
+  //
+  //  if (expr)
+  //  pfn = &function1;
+  //  else
+  //  pfn = &function2;
+  //
+  //  (*pfn)(arg list);
+  //
+
+  internal struct CallsiteInfo {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_CALLSITEINFO
+    internal int off;        // offset of call site
+    internal ushort ect;        // section index of call site
+    internal ushort pad0;       // alignment padding field, must be zero
+    internal uint typind;     // (type index) type index describing function signature
+  };
+
+  // Frame cookie information
+
+  internal enum CV_cookietype {
+    CV_COOKIETYPE_COPY=0,
+    CV_COOKIETYPE_XOR_SP,
+    CV_COOKIETYPE_XOR_BP,
+    CV_COOKIETYPE_XOR_R13,
+  };
+
+  // Symbol for describing security cookie's position and type
+  // (raw, xor'd with esp, xor'd with ebp).
+
+  internal struct FrameCookie {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_FRAMECOOKIE
+    internal int off;        // Frame relative offset
+    internal ushort reg;        // Register index
+    internal int cookietype; // (CV_cookietype) Type of the cookie
+    internal byte flags;      // Flags describing this cookie
+  };
+
+  internal enum CV_DISCARDED : uint {
+    CV_DISCARDED_UNKNOWN=0,
+    CV_DISCARDED_NOT_SELECTED=1,
+    CV_DISCARDED_NOT_REFERENCED=2,
+  };
+
+  internal struct DiscardedSym {
+    // internal ushort reclen;    // Record length [SYMTYPE]
+    // internal ushort rectyp;    // S_DISCARDED
+    internal CV_DISCARDED iscarded;
+    internal uint fileid;     // First FILEID if line number info present
+    internal uint linenum;    // First line number
+    internal byte[] data;       // Original record(s) with invalid indices
+  };
+
+  //
+  // V7 line number data types
+  //
+
+  internal enum DEBUG_S_SUBSECTION_TYPE : uint {
+    DEBUG_S_IGNORE=0x80000000,   // if this bit is set in a subsection type then ignore the subsection contents
+
+    DEBUG_S_SYMBOLS=0xf1,
+    DEBUG_S_LINES=0xf2,
+    DEBUG_S_STRINGTABLE=0xf3,
+    DEBUG_S_FILECHKSMS=0xf4,
+    DEBUG_S_FRAMEDATA=0xf5,
+  };
+
+  //
+  // Line flags (data present)
+  //
+  internal enum CV_LINE_SUBSECTION_FLAGS : ushort {
+    CV_LINES_HAVE_COLUMNS=0x0001,
+  }
+
+  internal struct CV_LineSection {
+    internal uint off;
+    internal ushort sec;
+    internal ushort flags;
+    internal uint cod;
+  }
+
+  internal struct CV_SourceFile {
+    internal uint index;          // Index to file in checksum section.
+    internal uint count;          // Number of CV_Line records.
+    internal uint linsiz;         // Size of CV_Line recods.
+  }
+
+  [Flags]
+  internal enum CV_Line_Flags : uint {
+    linenumStart=0x00ffffff,   // line where statement/expression starts
+    deltaLineEnd=0x7f000000,   // delta to line where statement ends (optional)
+    fStatement=0x80000000,   // true if a statement linenumber, else an expression line num
+  };
+
+  internal struct CV_Line {
+    internal uint offset;         // Offset to start of code bytes for line number
+    internal uint flags;          // (CV_Line_Flags)
+  };
+
+  internal struct CV_Column {
+    internal ushort offColumnStart;
+    internal ushort offColumnEnd;
+  };
+
+  //  File information
+
+  internal enum CV_FILE_CHECKSUM_TYPE : byte {
+    None=0,
+    MD5=1,
+  };
+
+  internal struct CV_FileCheckSum {
+    internal uint name;           // Index of name in name table.
+    internal byte len;            // Hash length
+    internal byte type;           // Hash type
+  }
+
+  [Flags]
+  internal enum FRAMEDATA_FLAGS : uint {
+    fHasSEH=0x00000001,
+    fHasEH=0x00000002,
+    fIsFunctionStart=0x00000004,
+  };
+
+  internal struct FrameData {
+    internal uint ulRvaStart;
+    internal uint cbBlock;
+    internal uint cbLocals;
+    internal uint cbParams;
+    internal uint cbStkMax;
+    internal uint frameFunc;
+    internal ushort cbProlog;
+    internal ushort cbSavedRegs;
+    internal uint flags;          // (FRAMEDATA_FLAGS)
+  };
+
+  internal struct XFixupData {
+    internal ushort wType;
+    internal ushort wExtra;
+    internal uint rva;
+    internal uint rvaTarget;
+  };
+
+  internal enum DEBUG_S_SUBSECTION {
+    SYMBOLS=0xF1,
+    LINES=0xF2,
+    STRINGTABLE=0xF3,
+    FILECHKSMS=0xF4,
+    FRAMEDATA=0xF5,
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/CvInfo.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 6d3adc17e6ef7dc4fb6a5c1060cc88fb
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 111 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DataStream.cs

@@ -0,0 +1,111 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+using System.IO;
+
+namespace Microsoft.Cci.Pdb {
+  internal class DataStream {
+    internal DataStream() {
+    }
+
+    internal DataStream(int contentSize, BitAccess bits, int count) {
+      this.contentSize = contentSize;
+      if (count > 0) {
+        this.pages = new int[count];
+        bits.ReadInt32(this.pages);
+      }
+    }
+
+    internal void Read(PdbReader reader, BitAccess bits) {
+      bits.MinCapacity(contentSize);
+      Read(reader, 0, bits.Buffer, 0, contentSize);
+    }
+
+    internal void Read(PdbReader reader, int position,
+                     byte[] bytes, int offset, int data) {
+      if (position + data > contentSize) {
+        throw new PdbException("DataStream can't read off end of stream. " +
+                                       "(pos={0},siz={1})",
+                               position, data);
+      }
+      if (position == contentSize) {
+        return;
+      }
+
+      int left = data;
+      int page = position / reader.pageSize;
+      int rema = position % reader.pageSize;
+
+      // First get remained of first page.
+      if (rema != 0) {
+        int todo = reader.pageSize - rema;
+        if (todo > left) {
+          todo = left;
+        }
+
+        reader.Seek(pages[page], rema);
+        reader.Read(bytes, offset, todo);
+
+        offset += todo;
+        left -= todo;
+        page++;
+      }
+
+      // Now get the remaining pages.
+      while (left > 0) {
+        int todo = reader.pageSize;
+        if (todo > left) {
+          todo = left;
+        }
+
+        reader.Seek(pages[page], 0);
+        reader.Read(bytes, offset, todo);
+
+        offset += todo;
+        left -= todo;
+        page++;
+      }
+    }
+
+    //private void AddPages(int page0, int count) {
+    //  if (pages == null) {
+    //    pages = new int[count];
+    //    for (int i = 0; i < count; i++) {
+    //      pages[i] = page0 + i;
+    //    }
+    //  } else {
+    //    int[] old = pages;
+    //    int used = old.Length;
+
+    //    pages = new int[used + count];
+    //    Array.Copy(old, pages, used);
+    //    for (int i = 0; i < count; i++) {
+    //      pages[used + i] = page0 + i;
+    //    }
+    //  }
+    //}
+
+    //internal int Pages {
+    //  get { return pages == null ? 0 : pages.Length; }
+    //}
+
+    internal int Length {
+      get { return contentSize; }
+    }
+
+    //internal int GetPage(int index) {
+    //  return pages[index];
+    //}
+
+    internal int contentSize;
+    internal int[] pages;
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DataStream.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 9d36d5901ca85764da4b9fdde7d4e741
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 41 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs

@@ -0,0 +1,41 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal struct DbiDbgHdr {
+    internal DbiDbgHdr(BitAccess bits) {
+      bits.ReadUInt16(out snFPO);
+      bits.ReadUInt16(out snException);
+      bits.ReadUInt16(out snFixup);
+      bits.ReadUInt16(out snOmapToSrc);
+      bits.ReadUInt16(out snOmapFromSrc);
+      bits.ReadUInt16(out snSectionHdr);
+      bits.ReadUInt16(out snTokenRidMap);
+      bits.ReadUInt16(out snXdata);
+      bits.ReadUInt16(out snPdata);
+      bits.ReadUInt16(out snNewFPO);
+      bits.ReadUInt16(out snSectionHdrOrig);
+    }
+
+    internal ushort snFPO;                 // 0..1
+    internal ushort snException;           // 2..3 (deprecated)
+    internal ushort snFixup;               // 4..5
+    internal ushort snOmapToSrc;           // 6..7
+    internal ushort snOmapFromSrc;         // 8..9
+    internal ushort snSectionHdr;          // 10..11
+    internal ushort snTokenRidMap;         // 12..13
+    internal ushort snXdata;               // 14..15
+    internal ushort snPdata;               // 16..17
+    internal ushort snNewFPO;              // 18..19
+    internal ushort snSectionHdrOrig;      // 20..21
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 9054f0b25da22074aa0e4067381e5db2
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 59 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiHeader.cs

@@ -0,0 +1,59 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal struct DbiHeader {
+    internal DbiHeader(BitAccess bits) {
+      bits.ReadInt32(out sig);
+      bits.ReadInt32(out ver);
+      bits.ReadInt32(out age);
+      bits.ReadInt16(out gssymStream);
+      bits.ReadUInt16(out vers);
+      bits.ReadInt16(out pssymStream);
+      bits.ReadUInt16(out pdbver);
+      bits.ReadInt16(out symrecStream);
+      bits.ReadUInt16(out pdbver2);
+      bits.ReadInt32(out gpmodiSize);
+      bits.ReadInt32(out secconSize);
+      bits.ReadInt32(out secmapSize);
+      bits.ReadInt32(out filinfSize);
+      bits.ReadInt32(out tsmapSize);
+      bits.ReadInt32(out mfcIndex);
+      bits.ReadInt32(out dbghdrSize);
+      bits.ReadInt32(out ecinfoSize);
+      bits.ReadUInt16(out flags);
+      bits.ReadUInt16(out machine);
+      bits.ReadInt32(out reserved);
+    }
+
+    internal int sig;                        // 0..3
+    internal int ver;                        // 4..7
+    internal int age;                        // 8..11
+    internal short gssymStream;                // 12..13
+    internal ushort vers;                       // 14..15
+    internal short pssymStream;                // 16..17
+    internal ushort pdbver;                     // 18..19
+    internal short symrecStream;               // 20..21
+    internal ushort pdbver2;                    // 22..23
+    internal int gpmodiSize;                 // 24..27
+    internal int secconSize;                 // 28..31
+    internal int secmapSize;                 // 32..35
+    internal int filinfSize;                 // 36..39
+    internal int tsmapSize;                  // 40..43
+    internal int mfcIndex;                   // 44..47
+    internal int dbghdrSize;                 // 48..51
+    internal int ecinfoSize;                 // 52..55
+    internal ushort flags;                      // 56..57
+    internal ushort machine;                    // 58..59
+    internal int reserved;                   // 60..63
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiHeader.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 35eb882f72928a247a97b963c4b7271e
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 57 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs

@@ -0,0 +1,57 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal class DbiModuleInfo {
+    internal DbiModuleInfo(BitAccess bits, bool readStrings) {
+      bits.ReadInt32(out opened);
+      new DbiSecCon(bits);
+      bits.ReadUInt16(out flags);
+      bits.ReadInt16(out stream);
+      bits.ReadInt32(out cbSyms);
+      bits.ReadInt32(out cbOldLines);
+      bits.ReadInt32(out cbLines);
+      bits.ReadInt16(out files);
+      bits.ReadInt16(out pad1);
+      bits.ReadUInt32(out offsets);
+      bits.ReadInt32(out niSource);
+      bits.ReadInt32(out niCompiler);
+      if (readStrings) {
+        bits.ReadCString(out moduleName);
+        bits.ReadCString(out objectName);
+      } else {
+        bits.SkipCString(out moduleName);
+        bits.SkipCString(out objectName);
+      }
+      bits.Align(4);
+      //if (opened != 0 || pad1 != 0) {
+      //  throw new PdbException("Invalid DBI module. "+
+      //                                 "(opened={0}, pad={1})", opened, pad1);
+      //}
+    }
+
+    internal int opened;                 //  0..3
+    //internal DbiSecCon section;                //  4..31
+    internal ushort flags;                  // 32..33
+    internal short stream;                 // 34..35
+    internal int cbSyms;                 // 36..39
+    internal int cbOldLines;             // 40..43
+    internal int cbLines;                // 44..57
+    internal short files;                  // 48..49
+    internal short pad1;                   // 50..51
+    internal uint offsets;
+    internal int niSource;
+    internal int niCompiler;
+    internal string moduleName;
+    internal string objectName;
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: fd96a8743bdb94d438eee9e546ffbc94
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 42 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiSecCon.cs

@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal struct DbiSecCon {
+    internal DbiSecCon(BitAccess bits) {
+      bits.ReadInt16(out section);
+      bits.ReadInt16(out pad1);
+      bits.ReadInt32(out offset);
+      bits.ReadInt32(out size);
+      bits.ReadUInt32(out flags);
+      bits.ReadInt16(out module);
+      bits.ReadInt16(out pad2);
+      bits.ReadUInt32(out dataCrc);
+      bits.ReadUInt32(out relocCrc);
+      //if (pad1 != 0 || pad2 != 0) {
+      //  throw new PdbException("Invalid DBI section. "+
+      //                                 "(pad1={0}, pad2={1})",
+      //                         pad1, pad2);
+      //}
+    }
+
+    internal short section;                    // 0..1
+    internal short pad1;                       // 2..3
+    internal int offset;                     // 4..7
+    internal int size;                       // 8..11
+    internal uint flags;                      // 12..15
+    internal short module;                     // 16..17
+    internal short pad2;                       // 18..19
+    internal uint dataCrc;                    // 20..23
+    internal uint relocCrc;                   // 24..27
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiSecCon.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 01d35df15c463064d9836a7a41fd65f5
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 583 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/IntHashTable.cs

@@ -0,0 +1,583 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+using System.Collections;
+
+namespace Microsoft.Cci.Pdb {
+  // The IntHashTable class represents a dictionary of associated keys and
+  // values with constant lookup time.
+  //
+  // Objects used as keys in a hashtable must implement the GetHashCode
+  // and Equals methods (or they can rely on the default implementations
+  // inherited from Object if key equality is simply reference
+  // equality). Furthermore, the GetHashCode and Equals methods of
+  // a key object must produce the same results given the same parameters
+  // for the entire time the key is present in the hashtable. In practical
+  // terms, this means that key objects should be immutable, at least for
+  // the time they are used as keys in a hashtable.
+  //
+  // When entries are added to a hashtable, they are placed into
+  // buckets based on the hashcode of their keys. Subsequent lookups of
+  // keys will use the hashcode of the keys to only search a particular
+  // bucket, thus substantially reducing the number of key comparisons
+  // required to find an entry. A hashtable's maximum load factor, which
+  // can be specified when the hashtable is instantiated, determines the
+  // maximum ratio of hashtable entries to hashtable buckets. Smaller load
+  // factors cause faster average lookup times at the cost of increased
+  // memory consumption. The default maximum load factor of 1.0 generally
+  // provides the best balance between speed and size. As entries are added
+  // to a hashtable, the hashtable's actual load factor increases, and when
+  // the actual load factor reaches the maximum load factor value, the
+  // number of buckets in the hashtable is automatically increased by
+  // approximately a factor of two (to be precise, the number of hashtable
+  // buckets is increased to the smallest prime number that is larger than
+  // twice the current number of hashtable buckets).
+  //
+  // Each object provides their own hash function, accessed by calling
+  // GetHashCode().  However, one can write their own object
+  // implementing IHashCodeProvider and pass it to a constructor on
+  // the IntHashTable.  That hash function would be used for all objects in
+  // the table.
+  //
+  // This IntHashTable is implemented to support multiple concurrent readers
+  // and one concurrent writer without using any synchronization primitives.
+  // All read methods essentially must protect themselves from a resize
+  // occuring while they are running.  This was done by enforcing an
+  // ordering on inserts & removes, as well as removing some member variables
+  // and special casing the expand code to work in a temporary array instead
+  // of the live bucket array.  All inserts must set a bucket's value and
+  // key before setting the hash code & collision field.
+  //
+  // By Brian Grunkemeyer, algorithm by Patrick Dussud.
+  // Version 1.30 2/20/2000
+  //| <include path='docs/doc[@for="IntHashTable"]/*' />
+  internal class IntHashTable {//: IEnumerable {
+    /*
+      Implementation Notes:
+
+      This IntHashTable uses double hashing.  There are hashsize buckets in
+      the table, and each bucket can contain 0 or 1 element.  We a bit to
+      mark whether there's been a collision when we inserted multiple
+      elements (ie, an inserted item was hashed at least a second time and
+      we probed this bucket, but it was already in use).  Using the
+      collision bit, we can terminate lookups & removes for elements that
+      aren't in the hash table more quickly.  We steal the most
+      significant bit from the hash code to store the collision bit.
+
+      Our hash function is of the following form:
+
+      h(key, n) = h1(key) + n*h2(key)
+
+      where n is the number of times we've hit a collided bucket and
+      rehashed (on this particular lookup).  Here are our hash functions:
+
+      h1(key) = GetHash(key);  // default implementation calls key.GetHashCode();
+      h2(key) = 1 + (((h1(key) >> 5) + 1) % (hashsize - 1));
+
+      The h1 can return any number.  h2 must return a number between 1 and
+      hashsize - 1 that is relatively prime to hashsize (not a problem if
+      hashsize is prime).  (Knuth's Art of Computer Programming, Vol. 3,
+      p. 528-9)
+
+      If this is true, then we are guaranteed to visit every bucket in
+      exactly hashsize probes, since the least common multiple of hashsize
+      and h2(key) will be hashsize * h2(key).  (This is the first number
+      where adding h2 to h1 mod hashsize will be 0 and we will search the
+      same bucket twice).
+
+      We previously used a different h2(key, n) that was not constant.
+      That is a horrifically bad idea, unless you can prove that series
+      will never produce any identical numbers that overlap when you mod
+      them by hashsize, for all subranges from i to i+hashsize, for all i.
+      It's not worth investigating, since there was no clear benefit from
+      using that hash function, and it was broken.
+
+      For efficiency reasons, we've implemented this by storing h1 and h2
+      in a temporary, and setting a variable called seed equal to h1.  We
+      do a probe, and if we collided, we simply add h2 to seed each time
+      through the loop.
+
+      A good test for h2() is to subclass IntHashTable, provide your own
+      implementation of GetHash() that returns a constant, then add many
+      items to the hash table.  Make sure Count equals the number of items
+      you inserted.
+
+      -- Brian Grunkemeyer, 10/28/1999
+    */
+
+    // A typical resize algorithm would pick the smallest prime number in this array
+    // that is larger than twice the previous capacity.
+    // Suppose our Hashtable currently has capacity x and enough elements are added
+    // such that a resize needs to occur. Resizing first computes 2x then finds the
+    // first prime in the table greater than 2x, i.e. if primes are ordered
+    // p_1, p_2, ? p_i,? it finds p_n such that p_n-1 < 2x < p_n.
+    // Doubling is important for preserving the asymptotic complexity of the
+    // hashtable operations such as add.  Having a prime guarantees that double
+    // hashing does not lead to infinite loops.  IE, your hash function will be
+    // h1(key) + i*h2(key), 0 <= i < size.  h2 and the size must be relatively prime.
+    private static readonly int[] primes = {
+            3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919,
+            1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591,
+            17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437,
+            187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263,
+            1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369};
+
+    private static int GetPrime(int minSize) {
+      if (minSize < 0) {
+        throw new ArgumentException("Arg_HTCapacityOverflow");
+      }
+      for (int i = 0; i < primes.Length; i++) {
+        int size = primes[i];
+        if (size >= minSize) {
+          return size;
+        }
+      }
+      throw new ArgumentException("Arg_HTCapacityOverflow");
+    }
+
+    // Deleted entries have their key set to buckets
+
+    // The hash table data.
+    // This cannot be serialised
+    private struct bucket {
+      internal int key;
+      internal int hash_coll;   // Store hash code; sign bit means there was a collision.
+      internal Object val;
+    }
+
+    private bucket[] buckets;
+
+    // The total number of entries in the hash table.
+    private int count;
+
+    // The total number of collision bits set in the hashtable
+    private int occupancy;
+
+    private int loadsize;
+    private int loadFactorPerc;    // 100 = 1.0
+
+    private int version;
+
+    // Constructs a new hashtable. The hashtable is created with an initial
+    // capacity of zero and a load factor of 1.0.
+    //| <include path='docs/doc[@for="IntHashTable.IntHashTable"]/*' />
+    internal IntHashTable()
+      : this(0, 100) {
+    }
+
+    //// Constructs a new hashtable with the given initial capacity and a load
+    //// factor of 1.0. The capacity argument serves as an indication of
+    //// the number of entries the hashtable will contain. When this number (or
+    //// an approximation) is known, specifying it in the constructor can
+    //// eliminate a number of resizing operations that would otherwise be
+    //// performed when elements are added to the hashtable.
+    ////
+    ////| <include path='docs/doc[@for="IntHashTable.IntHashTable1"]/*' />
+    //internal IntHashTable(int capacity)
+    //  : this(capacity, 100) {
+    //}
+
+    // Constructs a new hashtable with the given initial capacity and load
+    // factor. The capacity argument serves as an indication of the
+    // number of entries the hashtable will contain. When this number (or an
+    // approximation) is known, specifying it in the constructor can eliminate
+    // a number of resizing operations that would otherwise be performed when
+    // elements are added to the hashtable. The loadFactorPerc argument
+    // indicates the maximum ratio of hashtable entries to hashtable buckets.
+    // Smaller load factors cause faster average lookup times at the cost of
+    // increased memory consumption. A load factor of 1.0 generally provides
+    // the best balance between speed and size.
+    //
+    //| <include path='docs/doc[@for="IntHashTable.IntHashTable3"]/*' />
+    internal IntHashTable(int capacity, int loadFactorPerc) {
+      if (capacity < 0)
+        throw new ArgumentOutOfRangeException("capacity", "ArgumentOutOfRange_NeedNonNegNum");
+      if (!(loadFactorPerc >= 10 && loadFactorPerc <= 100))
+        throw new ArgumentOutOfRangeException("loadFactorPerc", String.Format("ArgumentOutOfRange_IntHashTableLoadFactor", 10, 100));
+
+      // Based on perf work, .72 is the optimal load factor for this table.
+      this.loadFactorPerc = (loadFactorPerc * 72) / 100;
+
+      int hashsize = GetPrime((int)(capacity / this.loadFactorPerc));
+      buckets = new bucket[hashsize];
+
+      loadsize = (int)(this.loadFactorPerc * hashsize) / 100;
+      if (loadsize >= hashsize)
+        loadsize = hashsize-1;
+    }
+
+    // Computes the hash function:  H(key, i) = h1(key) + i*h2(key, hashSize).
+    // The out parameter seed is h1(key), while the out parameter
+    // incr is h2(key, hashSize).  Callers of this function should
+    // add incr each time through a loop.
+    private static uint InitHash(int key, int hashsize, out uint seed, out uint incr) {
+      // Hashcode must be positive.  Also, we must not use the sign bit, since
+      // that is used for the collision bit.
+      uint hashcode = (uint)key & 0x7FFFFFFF;
+      seed = (uint)hashcode;
+      // Restriction: incr MUST be between 1 and hashsize - 1, inclusive for
+      // the modular arithmetic to work correctly.  This guarantees you'll
+      // visit every bucket in the table exactly once within hashsize
+      // iterations.  Violate this and it'll cause obscure bugs forever.
+      // If you change this calculation for h2(key), update putEntry too!
+      incr = (uint)(1 + (((seed >> 5) + 1) % ((uint)hashsize - 1)));
+      return hashcode;
+    }
+
+    // Adds an entry with the given key and value to this hashtable. An
+    // ArgumentException is thrown if the key is null or if the key is already
+    // present in the hashtable.
+    //
+    //| <include path='docs/doc[@for="IntHashTable.Add"]/*' />
+    internal void Add(int key, Object value) {
+      Insert(key, value, true);
+    }
+
+    //// Removes all entries from this hashtable.
+    ////| <include path='docs/doc[@for="IntHashTable.Clear"]/*' />
+    //internal void Clear() {
+    //  if (count == 0)
+    //    return;
+
+    //  for (int i = 0; i < buckets.Length; i++) {
+    //    buckets[i].hash_coll = 0;
+    //    buckets[i].key = -1;
+    //    buckets[i].val = null;
+    //  }
+
+    //  count = 0;
+    //  occupancy = 0;
+    //}
+
+    // Checks if this hashtable contains an entry with the given key.  This is
+    // an O(1) operation.
+    //
+    //| <include path='docs/doc[@for="IntHashTable.Contains"]/*' />
+    //internal bool Contains(int key) {
+    //  if (key < 0) {
+    //    throw new ArgumentException("Argument_KeyLessThanZero");
+    //  }
+
+    //  uint seed;
+    //  uint incr;
+    //  // Take a snapshot of buckets, in case another thread resizes table
+    //  bucket[] lbuckets = buckets;
+    //  uint hashcode = InitHash(key, lbuckets.Length, out seed, out incr);
+    //  int ntry = 0;
+
+    //  bucket b;
+    //  do {
+    //    int bucketNumber = (int)(seed % (uint)lbuckets.Length);
+    //    b = lbuckets[bucketNumber];
+    //    if (b.val == null) {
+    //      return false;
+    //    }
+    //    if (((b.hash_coll & 0x7FFFFFFF) == hashcode) && b.key == key) {
+    //      return true;
+    //    }
+    //    seed += incr;
+    //  } while (b.hash_coll < 0 && ++ntry < lbuckets.Length);
+    //  return false;
+    //}
+
+    // Returns the value associated with the given key. If an entry with the
+    // given key is not found, the returned value is null.
+    //
+    //| <include path='docs/doc[@for="IntHashTable.this"]/*' />
+    internal Object this[int key] {
+      get {
+        if (key < 0) {
+          throw new ArgumentException("Argument_KeyLessThanZero");
+        }
+        uint seed;
+        uint incr;
+        // Take a snapshot of buckets, in case another thread does a resize
+        bucket[] lbuckets = buckets;
+        uint hashcode = InitHash(key, lbuckets.Length, out seed, out incr);
+        int ntry = 0;
+
+        bucket b;
+        do {
+          int bucketNumber = (int)(seed % (uint)lbuckets.Length);
+          b = lbuckets[bucketNumber];
+          if (b.val == null) {
+            return null;
+          }
+          if (((b.hash_coll & 0x7FFFFFFF) == hashcode) && key == b.key) {
+            return b.val;
+          }
+          seed += incr;
+        } while (b.hash_coll < 0 && ++ntry < lbuckets.Length);
+        return null;
+      }
+      //set {
+      //  Insert(key, value, false);
+      //}
+    }
+
+    // Increases the bucket count of this hashtable. This method is called from
+    // the Insert method when the actual load factor of the hashtable reaches
+    // the upper limit specified when the hashtable was constructed. The number
+    // of buckets in the hashtable is increased to the smallest prime number
+    // that is larger than twice the current number of buckets, and the entries
+    // in the hashtable are redistributed into the new buckets using the cached
+    // hashcodes.
+    private void expand() {
+      rehash(GetPrime(1+buckets.Length*2));
+    }
+
+    // We occationally need to rehash the table to clean up the collision bits.
+    private void rehash() {
+      rehash(buckets.Length);
+    }
+
+    private void rehash(int newsize) {
+
+      // reset occupancy
+      occupancy=0;
+
+      // Don't replace any internal state until we've finished adding to the
+      // new bucket[].  This serves two purposes:
+      //   1) Allow concurrent readers to see valid hashtable contents
+      //      at all times
+      //   2) Protect against an OutOfMemoryException while allocating this
+      //      new bucket[].
+      bucket[] newBuckets = new bucket[newsize];
+
+      // rehash table into new buckets
+      int nb;
+      for (nb = 0; nb < buckets.Length; nb++) {
+        bucket oldb = buckets[nb];
+        if (oldb.val != null) {
+          putEntry(newBuckets, oldb.key, oldb.val, oldb.hash_coll & 0x7FFFFFFF);
+        }
+      }
+
+      // New bucket[] is good to go - replace buckets and other internal state.
+      version++;
+      buckets = newBuckets;
+      loadsize = (int)(loadFactorPerc * newsize) / 100;
+
+      if (loadsize >= newsize) {
+        loadsize = newsize-1;
+      }
+
+      return;
+    }
+
+    // Returns an enumerator for this hashtable.
+    // If modifications made to the hashtable while an enumeration is
+    // in progress, the MoveNext and Current methods of the
+    // enumerator will throw an exception.
+    //
+    //| <include path='docs/doc[@for="IntHashTable.IEnumerable.GetEnumerator"]/*' />
+    //IEnumerator IEnumerable.GetEnumerator() {
+    //  return new IntHashTableEnumerator(this);
+    //}
+
+    // Internal method to compare two keys.
+    //
+    // Inserts an entry into this hashtable. This method is called from the Set
+    // and Add methods. If the add parameter is true and the given key already
+    // exists in the hashtable, an exception is thrown.
+    private void Insert(int key, Object nvalue, bool add) {
+      if (key < 0) {
+        throw new ArgumentException("Argument_KeyLessThanZero");
+      }
+      if (nvalue == null) {
+        throw new ArgumentNullException("nvalue", "ArgumentNull_Value");
+      }
+      if (count >= loadsize) {
+        expand();
+      } else if (occupancy > loadsize && count > 100) {
+        rehash();
+      }
+
+      uint seed;
+      uint incr;
+      // Assume we only have one thread writing concurrently.  Modify
+      // buckets to contain new data, as long as we insert in the right order.
+      uint hashcode = InitHash(key, buckets.Length, out seed, out incr);
+      int ntry = 0;
+      int emptySlotNumber = -1; // We use the empty slot number to cache the first empty slot. We chose to reuse slots
+      // create by remove that have the collision bit set over using up new slots.
+
+      do {
+        int bucketNumber = (int)(seed % (uint)buckets.Length);
+
+        // Set emptySlot number to current bucket if it is the first available bucket that we have seen
+        // that once contained an entry and also has had a collision.
+        // We need to search this entire collision chain because we have to ensure that there are no
+        // duplicate entries in the table.
+
+        // Insert the key/value pair into this bucket if this bucket is empty and has never contained an entry
+        // OR
+        // This bucket once contained an entry but there has never been a collision
+        if (buckets[bucketNumber].val == null) {
+          // If we have found an available bucket that has never had a collision, but we've seen an available
+          // bucket in the past that has the collision bit set, use the previous bucket instead
+          if (emptySlotNumber != -1) { // Reuse slot
+            bucketNumber = emptySlotNumber;
+          }
+
+          // We pretty much have to insert in this order.  Don't set hash
+          // code until the value & key are set appropriately.
+          buckets[bucketNumber].val = nvalue;
+          buckets[bucketNumber].key = key;
+          buckets[bucketNumber].hash_coll |= (int)hashcode;
+          count++;
+          version++;
+          return;
+        }
+
+        // The current bucket is in use
+        // OR
+        // it is available, but has had the collision bit set and we have already found an available bucket
+        if (((buckets[bucketNumber].hash_coll & 0x7FFFFFFF) == hashcode) &&
+                    key == buckets[bucketNumber].key) {
+          if (add) {
+            throw new ArgumentException("Argument_AddingDuplicate__" + buckets[bucketNumber].key);
+          }
+          buckets[bucketNumber].val = nvalue;
+          version++;
+          return;
+        }
+
+        // The current bucket is full, and we have therefore collided.  We need to set the collision bit
+        // UNLESS
+        // we have remembered an available slot previously.
+        if (emptySlotNumber == -1) {// We don't need to set the collision bit here since we already have an empty slot
+          if (buckets[bucketNumber].hash_coll >= 0) {
+            buckets[bucketNumber].hash_coll |= unchecked((int)0x80000000);
+            occupancy++;
+          }
+        }
+        seed += incr;
+      } while (++ntry < buckets.Length);
+
+      // This code is here if and only if there were no buckets without a collision bit set in the entire table
+      if (emptySlotNumber != -1) {
+        // We pretty much have to insert in this order.  Don't set hash
+        // code until the value & key are set appropriately.
+        buckets[emptySlotNumber].val = nvalue;
+        buckets[emptySlotNumber].key  = key;
+        buckets[emptySlotNumber].hash_coll |= (int)hashcode;
+        count++;
+        version++;
+        return;
+
+      }
+
+      // If you see this assert, make sure load factor & count are reasonable.
+      // Then verify that our double hash function (h2, described at top of file)
+      // meets the requirements described above. You should never see this assert.
+      throw new InvalidOperationException("InvalidOperation_HashInsertFailed");
+    }
+
+    private void putEntry(bucket[] newBuckets, int key, Object nvalue, int hashcode) {
+      uint seed = (uint)hashcode;
+      uint incr = (uint)(1 + (((seed >> 5) + 1) % ((uint)newBuckets.Length - 1)));
+
+      do {
+        int bucketNumber = (int)(seed % (uint)newBuckets.Length);
+
+        if ((newBuckets[bucketNumber].val == null)) {
+          newBuckets[bucketNumber].val = nvalue;
+          newBuckets[bucketNumber].key = key;
+          newBuckets[bucketNumber].hash_coll |= hashcode;
+          return;
+        }
+
+        if (newBuckets[bucketNumber].hash_coll >= 0) {
+          newBuckets[bucketNumber].hash_coll |= unchecked((int)0x80000000);
+          occupancy++;
+        }
+        seed += incr;
+      } while (true);
+    }
+
+    // Returns the number of associations in this hashtable.
+    //
+    //| <include path='docs/doc[@for="IntHashTable.Count"]/*' />
+    //internal int Count {
+    //  get { return count; }
+    //}
+
+    // Implements an enumerator for a hashtable. The enumerator uses the
+    // internal version number of the hashtabke to ensure that no modifications
+    // are made to the hashtable while an enumeration is in progress.
+    //private class IntHashTableEnumerator : IEnumerator {
+    //  private IntHashTable hashtable;
+    //  private int bucket;
+    //  private int version;
+    //  private bool current;
+    //  //private int currentKey;
+    //  private Object currentValue;
+
+    //  internal IntHashTableEnumerator(IntHashTable hashtable) {
+    //    this.hashtable = hashtable;
+    //    bucket = hashtable.buckets.Length;
+    //    version = hashtable.version;
+    //  }
+
+    //  public bool MoveNext() {
+    //    if (version != hashtable.version)
+    //      throw new InvalidOperationException("InvalidOperation_EnumFailedVersion");
+    //    while (bucket > 0) {
+    //      bucket--;
+    //      Object val = hashtable.buckets[bucket].val;
+    //      if (val != null) {
+    //        //currentKey = hashtable.buckets[bucket].key;
+    //        currentValue = val;
+    //        current = true;
+    //        return true;
+    //      }
+    //    }
+    //    current = false;
+    //    return false;
+    //  }
+
+    //  //internal int Key {
+    //  //  get {
+    //  //    if (current == false)
+    //  //      throw new InvalidOperationException("InvalidOperation_EnumOpCantHappen");
+    //  //    return currentKey;
+    //  //  }
+    //  //}
+
+    //  public Object Current {
+    //    get {
+    //      if (current == false)
+    //        throw new InvalidOperationException("InvalidOperation_EnumOpCantHappen");
+    //      return currentValue;
+    //    }
+    //  }
+
+    //  //public Object Value {
+    //  //  get {
+    //  //    if (version != hashtable.version)
+    //  //      throw new InvalidOperationException("InvalidOperation_EnumFailedVersion");
+    //  //    if (current == false)
+    //  //      throw new InvalidOperationException("InvalidOperation_EnumOpCantHappen");
+    //  //    return currentValue;
+    //  //  }
+    //  //}
+
+    //  public void Reset() {
+    //    if (version != hashtable.version) throw new InvalidOperationException("InvalidOperation_EnumFailedVersion");
+    //    current = false;
+    //    bucket = hashtable.buckets.Length;
+    //    //currentKey = -1;
+    //    currentValue = null;
+    //  }
+    //}
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/IntHashTable.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d008a5db342192d4186b0f023232a9db
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 77 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/Interfaces.cs

@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.Cci {
+
+  /// <summary>
+  /// A range of CLR IL operations that comprise a lexical scope, specified as an IL offset and a length.
+  /// </summary>
+  public interface ILocalScope {
+    /// <summary>
+    /// The offset of the first operation in the scope.
+    /// </summary>
+    uint Offset { get; }
+
+    /// <summary>
+    /// The length of the scope. Offset+Length equals the offset of the first operation outside the scope, or equals the method body length.
+    /// </summary>
+    uint Length { get; }
+  }
+
+  /// <summary>
+  /// A description of the lexical scope in which a namespace type has been nested. This scope is tied to a particular
+  /// method body, so that partial types can be accommodated.
+  /// </summary>
+  public interface INamespaceScope {
+
+    /// <summary>
+    /// Zero or more used namespaces. These correspond to using clauses in C#.
+    /// </summary>
+    IEnumerable<IUsedNamespace> UsedNamespaces { get; }
+
+  }
+
+
+  /// <summary>
+  /// A namespace that is used (imported) inside a namespace scope.
+  /// </summary>
+  public interface IUsedNamespace {
+    /// <summary>
+    /// An alias for a namespace. For example the "x" of "using x = y.z;" in C#. Empty if no alias is present.
+    /// </summary>
+    IName Alias { get; }
+
+    /// <summary>
+    /// The name of a namepace that has been aliased.  For example the "y.z" of "using x = y.z;" or "using y.z" in C#.
+    /// </summary>
+    IName NamespaceName { get; }
+  }
+
+  /// <summary>
+  /// The name of an entity. Typically name instances come from a common pool. Within the pool no two distinct instances will have the same Value or UniqueKey.
+  /// </summary>
+  public interface IName {
+    /// <summary>
+    /// An integer that is unique within the pool from which the name instance has been allocated. Useful as a hashtable key.
+    /// </summary>
+    int UniqueKey {
+      get;
+        //^ ensures result > 0;
+    }
+
+    /// <summary>
+    /// An integer that is unique within the pool from which the name instance has been allocated. Useful as a hashtable key.
+    /// All name instances in the pool that have the same string value when ignoring the case of the characters in the string
+    /// will have the same key value.
+    /// </summary>
+    int UniqueKeyIgnoringCase {
+      get;
+      //^ ensures result > 0;
+    }
+
+    /// <summary>
+    /// The string value corresponding to this name.
+    /// </summary>
+    string Value { get; }
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/Interfaces.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 8dd8854d517038e41a2f325bf99340ab
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 58 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/MsfDirectory.cs

@@ -0,0 +1,58 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal class MsfDirectory {
+    internal MsfDirectory(PdbReader reader, PdbFileHeader head, BitAccess bits) {
+      int pages = reader.PagesFromSize(head.directorySize);
+
+      // 0..n in page of directory pages.
+      bits.MinCapacity(head.directorySize);
+      int directoryRootPages = head.directoryRoot.Length;
+      int pagesPerPage = head.pageSize / 4;
+      int pagesToGo = pages;
+      for (int i = 0; i < directoryRootPages; i++) {
+        int pagesInThisPage = pagesToGo <= pagesPerPage ? pagesToGo : pagesPerPage;
+        reader.Seek(head.directoryRoot[i], 0);
+        bits.Append(reader.reader, pagesInThisPage * 4);
+        pagesToGo -= pagesInThisPage;
+      }
+      bits.Position = 0;
+
+      DataStream stream = new DataStream(head.directorySize, bits, pages);
+      bits.MinCapacity(head.directorySize);
+      stream.Read(reader, bits);
+
+      // 0..3 in directory pages
+      int count;
+      bits.ReadInt32(out count);
+
+      // 4..n
+      int[] sizes = new int[count];
+      bits.ReadInt32(sizes);
+
+      // n..m
+      streams = new DataStream[count];
+      for (int i = 0; i < count; i++) {
+        if (sizes[i] <= 0) {
+          streams[i] = new DataStream();
+        } else {
+          streams[i] = new DataStream(sizes[i], bits,
+                                      reader.PagesFromSize(sizes[i]));
+        }
+      }
+    }
+
+    internal DataStream[] streams;
+  }
+
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/MsfDirectory.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 83e220691c827d34d9f2eb2ee1eced4a
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 89 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbConstant.cs

@@ -0,0 +1,89 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+using System.Runtime.InteropServices;
+
+namespace Microsoft.Cci.Pdb {
+  internal class PdbConstant {
+    internal string name;
+    internal uint token;
+    internal object value;
+
+    internal PdbConstant(BitAccess bits) {
+      bits.ReadUInt32(out this.token);
+      byte tag1;
+      bits.ReadUInt8(out tag1);
+      byte tag2;
+      bits.ReadUInt8(out tag2);
+      if (tag2 == 0) {
+        this.value = tag1;
+      } else if (tag2 == 0x80) {
+        switch (tag1) {
+          case 0x00: //sbyte
+            sbyte sb;
+            bits.ReadInt8(out sb);
+            this.value = sb;
+            break;
+          case 0x01: //short
+            short s;
+            bits.ReadInt16(out s);
+            this.value = s;
+            break;
+          case 0x02: //ushort
+            ushort us;
+            bits.ReadUInt16(out us);
+            this.value = us;
+            break;
+          case 0x03: //int
+            int i;
+            bits.ReadInt32(out i);
+            this.value = i;
+            break;
+          case 0x04: //uint
+            uint ui;
+            bits.ReadUInt32(out ui);
+            this.value = ui;
+            break;
+          case 0x05: //float
+            this.value = bits.ReadFloat();
+            break;
+          case 0x06: //double
+            this.value = bits.ReadDouble();
+            break;
+          case 0x09: //long
+            long sl;
+            bits.ReadInt64(out sl);
+            this.value = sl;
+            break;
+          case 0x0a: //ulong
+            ulong ul;
+            bits.ReadUInt64(out ul);
+            this.value = ul;
+            break;
+          case 0x10: //string
+            string str;
+            bits.ReadBString(out str);
+            this.value = str;
+            break;
+          case 0x19: //decimal
+            this.value = bits.ReadDecimal();
+            break;
+          default:
+            //TODO: error
+            break;
+        }
+      } else {
+        //TODO: error
+      }
+      bits.ReadCString(out name);
+    }
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbConstant.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 01bfde1ac4901f242883cad6983464ec
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 20 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbDebugException.cs

@@ -0,0 +1,20 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+using System.IO;
+
+namespace Microsoft.Cci.Pdb {
+  internal class PdbDebugException : IOException {
+    internal PdbDebugException(String format, params object[] args)
+      : base(String.Format(format, args)) {
+    }
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbDebugException.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 74c3feed6aab4cd439e456343c90e0f2
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 20 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbException.cs

@@ -0,0 +1,20 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+using System.IO;
+
+namespace Microsoft.Cci.Pdb {
+  internal class PdbException : IOException {
+    internal PdbException(String format, params object[] args)
+      : base(String.Format(format, args)) {
+    }
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbException.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 82bf81b6f23a5dd4e8b40d4b3a35991b
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 439 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFile.cs

@@ -0,0 +1,439 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Diagnostics.SymbolStore;
+
+namespace Microsoft.Cci.Pdb {
+  internal class PdbFile {
+    private PdbFile()   // This class can't be instantiated.
+    {
+    }
+
+    static void LoadGuidStream(BitAccess bits, out Guid doctype, out Guid language, out Guid vendor) {
+      bits.ReadGuid(out language);
+      bits.ReadGuid(out vendor);
+      bits.ReadGuid(out doctype);
+    }
+
+    static Dictionary<string, int> LoadNameIndex(BitAccess bits, out int age, out Guid guid) {
+      Dictionary<string, int> result = new Dictionary<string, int>();
+      int ver;
+      int sig;
+      bits.ReadInt32(out ver);    //  0..3  Version
+      bits.ReadInt32(out sig);    //  4..7  Signature
+      bits.ReadInt32(out age);    //  8..11 Age
+      bits.ReadGuid(out guid);       // 12..27 GUID
+
+      //if (ver != 20000404) {
+      //  throw new PdbDebugException("Unsupported PDB Stream version {0}", ver);
+      //}
+
+      // Read string buffer.
+      int buf;
+      bits.ReadInt32(out buf);    // 28..31 Bytes of Strings
+
+      int beg = bits.Position;
+      int nxt = bits.Position + buf;
+
+      bits.Position = nxt;
+
+      // Read map index.
+      int cnt;        // n+0..3 hash size.
+      int max;        // n+4..7 maximum ni.
+
+      bits.ReadInt32(out cnt);
+      bits.ReadInt32(out max);
+
+      BitSet present = new BitSet(bits);
+      BitSet deleted = new BitSet(bits);
+      if (!deleted.IsEmpty) {
+        throw new PdbDebugException("Unsupported PDB deleted bitset is not empty.");
+      }
+
+      int j = 0;
+      for (int i = 0; i < max; i++) {
+        if (present.IsSet(i)) {
+          int ns;
+          int ni;
+          bits.ReadInt32(out ns);
+          bits.ReadInt32(out ni);
+
+          string name;
+          int saved = bits.Position;
+          bits.Position = beg + ns;
+          bits.ReadCString(out name);
+          bits.Position = saved;
+
+          result.Add(name.ToUpperInvariant(), ni);
+          j++;
+        }
+      }
+      if (j != cnt) {
+        throw new PdbDebugException("Count mismatch. ({0} != {1})", j, cnt);
+      }
+      return result;
+    }
+
+    static IntHashTable LoadNameStream(BitAccess bits) {
+      IntHashTable ht = new IntHashTable();
+
+      uint sig;
+      int ver;
+      bits.ReadUInt32(out sig);   //  0..3  Signature
+      bits.ReadInt32(out ver);    //  4..7  Version
+
+      // Read (or skip) string buffer.
+      int buf;
+      bits.ReadInt32(out buf);    //  8..11 Bytes of Strings
+
+      if (sig != 0xeffeeffe || ver != 1) {
+        throw new PdbDebugException("Unsupported Name Stream version. "+
+                                            "(sig={0:x8}, ver={1})",
+                                    sig, ver);
+      }
+      int beg = bits.Position;
+      int nxt = bits.Position + buf;
+      bits.Position = nxt;
+
+      // Read hash table.
+      int siz;
+      bits.ReadInt32(out siz);    // n+0..3 Number of hash buckets.
+      nxt = bits.Position;
+
+      for (int i = 0; i < siz; i++) {
+        int ni;
+        string name;
+
+        bits.ReadInt32(out ni);
+
+        if (ni != 0) {
+          int saved = bits.Position;
+          bits.Position = beg + ni;
+          bits.ReadCString(out name);
+          bits.Position = saved;
+
+          ht.Add(ni, name);
+        }
+      }
+      bits.Position = nxt;
+
+      return ht;
+    }
+
+    private static PdbFunction match = new PdbFunction();
+
+    private static int FindFunction(PdbFunction[] funcs, ushort sec, uint off) {
+      match.segment = sec;
+      match.address = off;
+
+      return Array.BinarySearch(funcs, match, PdbFunction.byAddress);
+    }
+
+    static void LoadManagedLines(PdbFunction[] funcs,
+                                 IntHashTable names,
+                                 BitAccess bits,
+                                 MsfDirectory dir,
+                                 Dictionary<string, int> nameIndex,
+                                 PdbReader reader,
+                                 uint limit) {
+      Array.Sort(funcs, PdbFunction.byAddressAndToken);
+      IntHashTable checks = new IntHashTable();
+
+      // Read the files first
+      int begin = bits.Position;
+      while (bits.Position < limit) {
+        int sig;
+        int siz;
+        bits.ReadInt32(out sig);
+        bits.ReadInt32(out siz);
+        int place = bits.Position;
+        int endSym = bits.Position + siz;
+
+        switch ((DEBUG_S_SUBSECTION)sig) {
+          case DEBUG_S_SUBSECTION.FILECHKSMS:
+            while (bits.Position < endSym) {
+              CV_FileCheckSum chk;
+
+              int ni = bits.Position - place;
+              bits.ReadUInt32(out chk.name);
+              bits.ReadUInt8(out chk.len);
+              bits.ReadUInt8(out chk.type);
+
+              string name = (string)names[(int)chk.name];
+              int guidStream;
+              Guid doctypeGuid = SymDocumentType.Text;
+              Guid languageGuid = Guid.Empty;
+              Guid vendorGuid = Guid.Empty;
+              if (nameIndex.TryGetValue("/SRC/FILES/"+name.ToUpperInvariant(), out guidStream)) {
+                var guidBits = new BitAccess(0x100);
+                dir.streams[guidStream].Read(reader, guidBits);
+                LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid);
+              }
+
+              PdbSource src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid);
+              checks.Add(ni, src);
+              bits.Position += chk.len;
+              bits.Align(4);
+            }
+            bits.Position = endSym;
+            break;
+
+          default:
+            bits.Position = endSym;
+            break;
+        }
+      }
+
+      // Read the lines next.
+      bits.Position = begin;
+      while (bits.Position < limit) {
+        int sig;
+        int siz;
+        bits.ReadInt32(out sig);
+        bits.ReadInt32(out siz);
+        int endSym = bits.Position + siz;
+
+        switch ((DEBUG_S_SUBSECTION)sig) {
+          case DEBUG_S_SUBSECTION.LINES: {
+              CV_LineSection sec;
+
+              bits.ReadUInt32(out sec.off);
+              bits.ReadUInt16(out sec.sec);
+              bits.ReadUInt16(out sec.flags);
+              bits.ReadUInt32(out sec.cod);
+              int funcIndex = FindFunction(funcs, sec.sec, sec.off);
+              if (funcIndex < 0) break;
+              var func = funcs[funcIndex];
+              if (func.lines == null) {
+                while (funcIndex > 0) {
+                  var f = funcs[funcIndex-1];
+                  if (f.lines != null || f.segment != sec.sec || f.address != sec.off) break;
+                  func = f;
+                  funcIndex--;
+                }
+             } else {
+                while (funcIndex < funcs.Length-1 && func.lines != null) {
+                  var f = funcs[funcIndex+1];
+                  if (f.segment != sec.sec || f.address != sec.off) break;
+                  func = f;
+                  funcIndex++;
+                }
+              }
+              if (func.lines != null) break;
+
+              // Count the line blocks.
+              int begSym = bits.Position;
+              int blocks = 0;
+              while (bits.Position < endSym) {
+                CV_SourceFile file;
+                bits.ReadUInt32(out file.index);
+                bits.ReadUInt32(out file.count);
+                bits.ReadUInt32(out file.linsiz);   // Size of payload.
+                int linsiz = (int)file.count * (8 + ((sec.flags & 1) != 0 ? 4 : 0));
+                bits.Position += linsiz;
+                blocks++;
+              }
+
+              func.lines = new PdbLines[blocks];
+              int block = 0;
+
+              bits.Position = begSym;
+              while (bits.Position < endSym) {
+                CV_SourceFile file;
+                bits.ReadUInt32(out file.index);
+                bits.ReadUInt32(out file.count);
+                bits.ReadUInt32(out file.linsiz);   // Size of payload.
+
+                PdbSource src = (PdbSource)checks[(int)file.index];
+                PdbLines tmp = new PdbLines(src, file.count);
+                func.lines[block++] = tmp;
+                PdbLine[] lines = tmp.lines;
+
+                int plin = bits.Position;
+                int pcol = bits.Position + 8 * (int)file.count;
+
+                for (int i = 0; i < file.count; i++) {
+                  CV_Line line;
+                  CV_Column column = new CV_Column();
+
+                  bits.Position = plin + 8 * i;
+                  bits.ReadUInt32(out line.offset);
+                  bits.ReadUInt32(out line.flags);
+
+                  uint lineBegin = line.flags & (uint)CV_Line_Flags.linenumStart;
+                  uint delta = (line.flags & (uint)CV_Line_Flags.deltaLineEnd) >> 24;
+                  //bool statement = ((line.flags & (uint)CV_Line_Flags.fStatement) == 0);
+                  if ((sec.flags & 1) != 0) {
+                    bits.Position = pcol + 4 * i;
+                    bits.ReadUInt16(out column.offColumnStart);
+                    bits.ReadUInt16(out column.offColumnEnd);
+                  }
+
+                  lines[i] = new PdbLine(line.offset,
+                                         lineBegin,
+                                         column.offColumnStart,
+                                         lineBegin+delta,
+                                         column.offColumnEnd);
+                }
+              }
+              break;
+            }
+        }
+        bits.Position = endSym;
+      }
+    }
+
+    static void LoadFuncsFromDbiModule(BitAccess bits,
+                                       DbiModuleInfo info,
+                                       IntHashTable names,
+                                       ArrayList funcList,
+                                       bool readStrings,
+                                       MsfDirectory dir,
+                                       Dictionary<string, int> nameIndex,
+                                       PdbReader reader) {
+      PdbFunction[] funcs = null;
+
+      bits.Position = 0;
+      int sig;
+      bits.ReadInt32(out sig);
+      if (sig != 4) {
+        throw new PdbDebugException("Invalid signature. (sig={0})", sig);
+      }
+
+      bits.Position = 4;
+      // Console.WriteLine("{0}:", info.moduleName);
+      funcs = PdbFunction.LoadManagedFunctions(/*info.moduleName,*/
+                                               bits, (uint)info.cbSyms,
+                                               readStrings);
+      if (funcs != null) {
+        bits.Position = info.cbSyms + info.cbOldLines;
+        LoadManagedLines(funcs, names, bits, dir, nameIndex, reader,
+                         (uint)(info.cbSyms + info.cbOldLines + info.cbLines));
+
+        for (int i = 0; i < funcs.Length; i++) {
+          funcList.Add(funcs[i]);
+        }
+      }
+    }
+
+    static void LoadDbiStream(BitAccess bits,
+                              out DbiModuleInfo[] modules,
+                              out DbiDbgHdr header,
+                              bool readStrings) {
+      DbiHeader dh = new DbiHeader(bits);
+      header = new DbiDbgHdr();
+
+      //if (dh.sig != -1 || dh.ver != 19990903) {
+      //  throw new PdbException("Unsupported DBI Stream version, sig={0}, ver={1}",
+      //                         dh.sig, dh.ver);
+      //}
+
+      // Read gpmod section.
+      ArrayList modList = new ArrayList();
+      int end = bits.Position + dh.gpmodiSize;
+      while (bits.Position < end) {
+        DbiModuleInfo mod = new DbiModuleInfo(bits, readStrings);
+        modList.Add(mod);
+      }
+      if (bits.Position != end) {
+        throw new PdbDebugException("Error reading DBI stream, pos={0} != {1}",
+                                    bits.Position, end);
+      }
+
+      if (modList.Count > 0) {
+        modules = (DbiModuleInfo[])modList.ToArray(typeof(DbiModuleInfo));
+      } else {
+        modules = null;
+      }
+
+      // Skip the Section Contribution substream.
+      bits.Position += dh.secconSize;
+
+      // Skip the Section Map substream.
+      bits.Position += dh.secmapSize;
+
+      // Skip the File Info substream.
+      bits.Position += dh.filinfSize;
+
+      // Skip the TSM substream.
+      bits.Position += dh.tsmapSize;
+
+      // Skip the EC substream.
+      bits.Position += dh.ecinfoSize;
+
+      // Read the optional header.
+      end = bits.Position + dh.dbghdrSize;
+      if (dh.dbghdrSize > 0) {
+        header = new DbiDbgHdr(bits);
+      }
+      bits.Position = end;
+    }
+
+    internal static PdbFunction[] LoadFunctions(Stream read, bool readAllStrings, out int age, out Guid guid) {
+      BitAccess bits = new BitAccess(512 * 1024);
+      return LoadFunctions(read, bits, readAllStrings, out age, out guid);
+    }
+
+    internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool readAllStrings, out int age, out Guid guid) {
+      PdbFileHeader head = new PdbFileHeader(read, bits);
+      PdbReader reader = new PdbReader(read, head.pageSize);
+      MsfDirectory dir = new MsfDirectory(reader, head, bits);
+      DbiModuleInfo[] modules = null;
+      DbiDbgHdr header;
+
+      dir.streams[1].Read(reader, bits);
+      Dictionary<string, int> nameIndex = LoadNameIndex(bits, out age, out guid);
+      int nameStream;
+      if (!nameIndex.TryGetValue("/NAMES", out nameStream)) {
+        throw new PdbException("No `name' stream");
+      }
+
+      dir.streams[nameStream].Read(reader, bits);
+      IntHashTable names = LoadNameStream(bits);
+
+      dir.streams[3].Read(reader, bits);
+      LoadDbiStream(bits, out modules, out header, readAllStrings);
+
+      ArrayList funcList = new ArrayList();
+
+      if (modules != null) {
+        for (int m = 0; m < modules.Length; m++) {
+          if (modules[m].stream > 0) {
+            dir.streams[modules[m].stream].Read(reader, bits);
+            LoadFuncsFromDbiModule(bits, modules[m], names, funcList,
+                                   readAllStrings, dir, nameIndex, reader);
+          }
+        }
+      }
+
+      PdbFunction[] funcs = (PdbFunction[])funcList.ToArray(typeof(PdbFunction));
+
+      // After reading the functions, apply the token remapping table if it exists.
+      if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) {
+        dir.streams[header.snTokenRidMap].Read(reader, bits);
+        uint[] ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4];
+        bits.ReadUInt32(ridMap);
+
+        foreach (PdbFunction func in funcs) {
+          func.token = 0x06000000 | ridMap[func.token & 0xffffff];
+        }
+      }
+
+      //
+      Array.Sort(funcs, PdbFunction.byAddressAndToken);
+      //Array.Sort(funcs, PdbFunction.byToken);
+      return funcs;
+    }
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFile.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 28fb62bbc3a4f0c458a6e094d8102698
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 90 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs

@@ -0,0 +1,90 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+using System.IO;
+using System.Text;
+
+namespace Microsoft.Cci.Pdb {
+  internal class PdbFileHeader {
+    //internal PdbFileHeader(int pageSize) {
+    //  this.magic = new byte[32] {
+    //            0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, // "Microsof"
+    //            0x74, 0x20, 0x43, 0x2F, 0x43, 0x2B, 0x2B, 0x20, // "t C/C++ "
+    //            0x4D, 0x53, 0x46, 0x20, 0x37, 0x2E, 0x30, 0x30, // "MSF 7.00"
+    //            0x0D, 0x0A, 0x1A, 0x44, 0x53, 0x00, 0x00, 0x00  // "^^^DS^^^"
+    //        };
+    //  this.pageSize = pageSize;
+    //}
+
+    internal PdbFileHeader(Stream reader, BitAccess bits) {
+      bits.MinCapacity(56);
+      reader.Seek(0, SeekOrigin.Begin);
+      bits.FillBuffer(reader, 52);
+
+      this.magic = new byte[32];
+      bits.ReadBytes(this.magic);                 //   0..31
+      bits.ReadInt32(out this.pageSize);          //  32..35
+      bits.ReadInt32(out this.freePageMap);       //  36..39
+      bits.ReadInt32(out this.pagesUsed);         //  40..43
+      bits.ReadInt32(out this.directorySize);     //  44..47
+      bits.ReadInt32(out this.zero);              //  48..51
+
+      int directoryPages = ((((directorySize + pageSize - 1) / pageSize) * 4) + pageSize - 1) / pageSize;
+      this.directoryRoot = new int[directoryPages];
+      bits.FillBuffer(reader, directoryPages * 4);
+      bits.ReadInt32(this.directoryRoot);
+    }
+
+    //internal string Magic {
+    //  get { return StringFromBytesUTF8(magic); }
+    //}
+
+    //internal void Write(Stream writer, BitAccess bits) {
+    //  bits.MinCapacity(pageSize);
+    //  bits.WriteBytes(magic);                     //   0..31
+    //  bits.WriteInt32(pageSize);                  //  32..35
+    //  bits.WriteInt32(freePageMap);               //  36..39
+    //  bits.WriteInt32(pagesUsed);                 //  40..43
+    //  bits.WriteInt32(directorySize);             //  44..47
+    //  bits.WriteInt32(zero);                      //  48..51
+    //  bits.WriteInt32(directoryRoot);             //  52..55
+
+    //  writer.Seek(0, SeekOrigin.Begin);
+    //  bits.WriteBuffer(writer, pageSize);
+    //}
+
+    //////////////////////////////////////////////////// Helper Functions.
+    //
+    //internal static string StringFromBytesUTF8(byte[] bytes) {
+    //  return StringFromBytesUTF8(bytes, 0, bytes.Length);
+    //}
+
+    //internal static string StringFromBytesUTF8(byte[] bytes, int offset, int length) {
+    //  for (int i = 0; i < length; i++) {
+    //    if (bytes[offset + i] < ' ') {
+    //      length = i;
+    //    }
+    //  }
+    //  return Encoding.UTF8.GetString(bytes, offset, length);
+    //}
+
+    ////////////////////////////////////////////////////////////// Fields.
+    //
+    internal readonly byte[] magic;
+    internal readonly int pageSize;
+    internal int freePageMap;
+    internal int pagesUsed;
+    internal int directorySize;
+    internal readonly int zero;
+    internal int[] directoryRoot;
+  }
+
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d5025bab5751b8943987072ee49ad110
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 452 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFunction.cs

@@ -0,0 +1,452 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Microsoft.Cci.Pdb {
+  internal class PdbFunction {
+    static internal readonly Guid msilMetaData = new Guid(0xc6ea3fc9, 0x59b3, 0x49d6, 0xbc, 0x25,
+                                                        0x09, 0x02, 0xbb, 0xab, 0xb4, 0x60);
+    static internal readonly IComparer byAddress = new PdbFunctionsByAddress();
+    static internal readonly IComparer byAddressAndToken = new PdbFunctionsByAddressAndToken();
+    //static internal readonly IComparer byToken = new PdbFunctionsByToken();
+
+    internal uint token;
+    internal uint slotToken;
+    //internal string name;
+    //internal string module;
+    //internal ushort flags;
+
+    internal uint segment;
+    internal uint address;
+    //internal uint length;
+
+    //internal byte[] metadata;
+    internal PdbScope[] scopes;
+    internal PdbSlot[] slots;
+    internal PdbConstant[] constants;
+    internal string[] usedNamespaces;
+    internal PdbLines[] lines;
+    internal ushort[]/*?*/ usingCounts;
+    internal IEnumerable<INamespaceScope>/*?*/ namespaceScopes;
+    internal string/*?*/ iteratorClass;
+    internal List<ILocalScope>/*?*/ iteratorScopes;
+
+    private static string StripNamespace(string module) {
+      int li = module.LastIndexOf('.');
+      if (li > 0) {
+        return module.Substring(li + 1);
+      }
+      return module;
+    }
+
+
+    internal static PdbFunction[] LoadManagedFunctions(/*string module,*/
+                                                       BitAccess bits, uint limit,
+                                                       bool readStrings) {
+      //string mod = StripNamespace(module);
+      int begin = bits.Position;
+      int count = 0;
+
+      while (bits.Position < limit) {
+        ushort siz;
+        ushort rec;
+
+        bits.ReadUInt16(out siz);
+        int star = bits.Position;
+        int stop = bits.Position + siz;
+        bits.Position = star;
+        bits.ReadUInt16(out rec);
+
+        switch ((SYM)rec) {
+          case SYM.S_GMANPROC:
+          case SYM.S_LMANPROC:
+            ManProcSym proc;
+            bits.ReadUInt32(out proc.parent);
+            bits.ReadUInt32(out proc.end);
+            bits.Position = (int)proc.end;
+            count++;
+            break;
+
+          case SYM.S_END:
+            bits.Position = stop;
+            break;
+
+          default:
+            //Console.WriteLine("{0,6}: {1:x2} {2}",
+            //                  bits.Position, rec, (SYM)rec);
+            bits.Position = stop;
+            break;
+        }
+      }
+      if (count == 0) {
+        return null;
+      }
+
+      bits.Position = begin;
+      PdbFunction[] funcs = new PdbFunction[count];
+      int func = 0;
+
+      while (bits.Position < limit) {
+        ushort siz;
+        ushort rec;
+
+        bits.ReadUInt16(out siz);
+        int star = bits.Position;
+        int stop = bits.Position + siz;
+        bits.ReadUInt16(out rec);
+
+        switch ((SYM)rec) {
+
+          case SYM.S_GMANPROC:
+          case SYM.S_LMANPROC:
+            ManProcSym proc;
+            //int offset = bits.Position;
+
+            bits.ReadUInt32(out proc.parent);
+            bits.ReadUInt32(out proc.end);
+            bits.ReadUInt32(out proc.next);
+            bits.ReadUInt32(out proc.len);
+            bits.ReadUInt32(out proc.dbgStart);
+            bits.ReadUInt32(out proc.dbgEnd);
+            bits.ReadUInt32(out proc.token);
+            bits.ReadUInt32(out proc.off);
+            bits.ReadUInt16(out proc.seg);
+            bits.ReadUInt8(out proc.flags);
+            bits.ReadUInt16(out proc.retReg);
+            if (readStrings) {
+              bits.ReadCString(out proc.name);
+            } else {
+              bits.SkipCString(out proc.name);
+            }
+            //Console.WriteLine("token={0:X8} [{1}::{2}]", proc.token, module, proc.name);
+
+            bits.Position = stop;
+            funcs[func++] = new PdbFunction(/*module,*/ proc, bits);
+            break;
+
+          default: {
+              //throw new PdbDebugException("Unknown SYMREC {0}", (SYM)rec);
+              bits.Position = stop;
+              break;
+            }
+        }
+      }
+      return funcs;
+    }
+
+    internal static void CountScopesAndSlots(BitAccess bits, uint limit,
+                                             out int constants, out int scopes, out int slots, out int usedNamespaces) {
+      int pos = bits.Position;
+      BlockSym32 block;
+      constants = 0;
+      slots = 0;
+      scopes = 0;
+      usedNamespaces = 0;
+
+      while (bits.Position < limit) {
+        ushort siz;
+        ushort rec;
+
+        bits.ReadUInt16(out siz);
+        int star = bits.Position;
+        int stop = bits.Position + siz;
+        bits.Position = star;
+        bits.ReadUInt16(out rec);
+
+        switch ((SYM)rec) {
+          case SYM.S_BLOCK32: {
+              bits.ReadUInt32(out block.parent);
+              bits.ReadUInt32(out block.end);
+
+              scopes++;
+              bits.Position = (int)block.end;
+              break;
+            }
+
+          case SYM.S_MANSLOT:
+            slots++;
+            bits.Position = stop;
+            break;
+
+          case SYM.S_UNAMESPACE:
+            usedNamespaces++;
+            bits.Position = stop;
+            break;
+
+          case SYM.S_MANCONSTANT:
+            constants++;
+            bits.Position = stop;
+            break;
+
+          default:
+            bits.Position = stop;
+            break;
+        }
+      }
+      bits.Position = pos;
+    }
+
+    internal PdbFunction() {
+    }
+
+    internal PdbFunction(/*string module, */ManProcSym proc, BitAccess bits) {
+      this.token = proc.token;
+      //this.module = module;
+      //this.name = proc.name;
+      //this.flags = proc.flags;
+      this.segment = proc.seg;
+      this.address = proc.off;
+      //this.length = proc.len;
+
+      if (proc.seg != 1) {
+        throw new PdbDebugException("Segment is {0}, not 1.", proc.seg);
+      }
+      if (proc.parent != 0 || proc.next != 0) {
+        throw new PdbDebugException("Warning parent={0}, next={1}",
+                                    proc.parent, proc.next);
+      }
+      //if (proc.dbgStart != 0 || proc.dbgEnd != 0) {
+      //  throw new PdbDebugException("Warning DBG start={0}, end={1}",
+      //                              proc.dbgStart, proc.dbgEnd);
+      //}
+
+      int constantCount;
+      int scopeCount;
+      int slotCount;
+      int usedNamespacesCount;
+      CountScopesAndSlots(bits, proc.end, out constantCount, out scopeCount, out slotCount, out usedNamespacesCount);
+      int scope = constantCount > 0 || slotCount > 0 || usedNamespacesCount > 0 ? 1 : 0;
+      int slot = 0;
+      int constant = 0;
+      int usedNs = 0;
+      scopes = new PdbScope[scopeCount+scope];
+      slots = new PdbSlot[slotCount];
+      constants = new PdbConstant[constantCount];
+      usedNamespaces = new string[usedNamespacesCount];
+
+      if (scope > 0)
+        scopes[0] = new PdbScope(this.address, proc.len, slots, constants, usedNamespaces);
+
+      while (bits.Position < proc.end) {
+        ushort siz;
+        ushort rec;
+
+        bits.ReadUInt16(out siz);
+        int star = bits.Position;
+        int stop = bits.Position + siz;
+        bits.Position = star;
+        bits.ReadUInt16(out rec);
+
+        switch ((SYM)rec) {
+          case SYM.S_OEM: {          // 0x0404
+              OemSymbol oem;
+
+              bits.ReadGuid(out oem.idOem);
+              bits.ReadUInt32(out oem.typind);
+              // internal byte[]   rgl;        // user data, force 4-byte alignment
+
+              if (oem.idOem == msilMetaData) {
+                string name = bits.ReadString();
+                if (name == "MD2") {
+                  byte version;
+                  bits.ReadUInt8(out version);
+                  if (version == 4) {
+                    byte count;
+                    bits.ReadUInt8(out count);
+                    bits.Align(4);
+                    while (count-- > 0)
+                      this.ReadCustomMetadata(bits);
+                  }
+                }
+                bits.Position = stop;
+                break;
+              } else {
+                throw new PdbDebugException("OEM section: guid={0} ti={1}",
+                                            oem.idOem, oem.typind);
+                // bits.Position = stop;
+              }
+            }
+
+          case SYM.S_BLOCK32: {
+              BlockSym32 block = new BlockSym32();
+
+              bits.ReadUInt32(out block.parent);
+              bits.ReadUInt32(out block.end);
+              bits.ReadUInt32(out block.len);
+              bits.ReadUInt32(out block.off);
+              bits.ReadUInt16(out block.seg);
+              bits.SkipCString(out block.name);
+              bits.Position = stop;
+
+              scopes[scope++] = new PdbScope(this.address, block, bits, out slotToken);
+              bits.Position = (int)block.end;
+              break;
+            }
+
+          case SYM.S_MANSLOT:
+            uint typind;
+            slots[slot++] = new PdbSlot(bits, out typind);
+            bits.Position = stop;
+            break;
+
+          case SYM.S_MANCONSTANT:
+            constants[constant++] = new PdbConstant(bits);
+            bits.Position = stop;
+            break;
+
+          case SYM.S_UNAMESPACE:
+            bits.ReadCString(out usedNamespaces[usedNs++]);
+            bits.Position = stop;
+            break;
+
+          case SYM.S_END:
+            bits.Position = stop;
+            break;
+
+          default: {
+              //throw new PdbDebugException("Unknown SYM: {0}", (SYM)rec);
+              bits.Position = stop;
+              break;
+            }
+        }
+      }
+
+      if (bits.Position != proc.end) {
+        throw new PdbDebugException("Not at S_END");
+      }
+
+      ushort esiz;
+      ushort erec;
+      bits.ReadUInt16(out esiz);
+      bits.ReadUInt16(out erec);
+
+      if (erec != (ushort)SYM.S_END) {
+        throw new PdbDebugException("Missing S_END");
+      }
+    }
+
+    private void ReadCustomMetadata(BitAccess bits) {
+      int savedPosition = bits.Position;
+      byte version;
+      bits.ReadUInt8(out version);
+      if (version != 4) {
+        throw new PdbDebugException("Unknown custom metadata item version: {0}", version);
+      }
+      byte kind;
+      bits.ReadUInt8(out kind);
+      bits.Align(4);
+      uint numberOfBytesInItem;
+      bits.ReadUInt32(out numberOfBytesInItem);
+      switch (kind) {
+        case 0: this.ReadUsingInfo(bits); break;
+        case 1: break; // this.ReadForwardInfo(bits); break;
+        case 2: break; // this.ReadForwardedToModuleInfo(bits); break;
+        case 3: this.ReadIteratorLocals(bits); break;
+        case 4: this.ReadForwardIterator(bits); break;
+        default: throw new PdbDebugException("Unknown custom metadata item kind: {0}", kind);
+      }
+      bits.Position = savedPosition+(int)numberOfBytesInItem;
+    }
+
+    private void ReadForwardIterator(BitAccess bits) {
+      this.iteratorClass = bits.ReadString();
+    }
+
+    private void ReadIteratorLocals(BitAccess bits) {
+      uint numberOfLocals;
+      bits.ReadUInt32(out numberOfLocals);
+      this.iteratorScopes = new List<ILocalScope>((int)numberOfLocals);
+      while (numberOfLocals-- > 0) {
+        uint ilStartOffset;
+        uint ilEndOffset;
+        bits.ReadUInt32(out ilStartOffset);
+        bits.ReadUInt32(out ilEndOffset);
+        this.iteratorScopes.Add(new PdbIteratorScope(ilStartOffset, ilEndOffset-ilStartOffset));
+      }
+    }
+
+    //private void ReadForwardedToModuleInfo(BitAccess bits) {
+    //}
+
+    //private void ReadForwardInfo(BitAccess bits) {
+    //}
+
+    private void ReadUsingInfo(BitAccess bits) {
+      ushort numberOfNamespaces;
+      bits.ReadUInt16(out numberOfNamespaces);
+      this.usingCounts = new ushort[numberOfNamespaces];
+      for (ushort i = 0; i < numberOfNamespaces; i++) {
+        bits.ReadUInt16(out this.usingCounts[i]);
+      }
+    }
+
+    internal class PdbFunctionsByAddress : IComparer {
+      public int Compare(Object x, Object y) {
+        PdbFunction fx = (PdbFunction)x;
+        PdbFunction fy = (PdbFunction)y;
+
+        if (fx.segment < fy.segment) {
+          return -1;
+        } else if (fx.segment > fy.segment) {
+          return 1;
+        } else if (fx.address < fy.address) {
+          return -1;
+        } else if (fx.address > fy.address) {
+          return 1;
+        } else {
+          return 0;
+        }
+      }
+    }
+
+    internal class PdbFunctionsByAddressAndToken : IComparer {
+      public int Compare(Object x, Object y) {
+        PdbFunction fx = (PdbFunction)x;
+        PdbFunction fy = (PdbFunction)y;
+
+        if (fx.segment < fy.segment) {
+          return -1;
+        } else if (fx.segment > fy.segment) {
+          return 1;
+        } else if (fx.address < fy.address) {
+          return -1;
+        } else if (fx.address > fy.address) {
+          return 1;
+        } else {
+          if (fx.token < fy.token)
+            return -1;
+          else if (fx.token > fy.token)
+            return 1;
+          else
+            return 0;
+        }
+      }
+    }
+
+    //internal class PdbFunctionsByToken : IComparer {
+    //  public int Compare(Object x, Object y) {
+    //    PdbFunction fx = (PdbFunction)x;
+    //    PdbFunction fy = (PdbFunction)y;
+
+    //    if (fx.token < fy.token) {
+    //      return -1;
+    //    } else if (fx.token > fy.token) {
+    //      return 1;
+    //    } else {
+    //      return 0;
+    //    }
+    //  }
+
+    //}
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFunction.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bb487b62425b7154d8e59c3f427d63c3
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 29 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLine.cs

@@ -0,0 +1,29 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal struct PdbLine {
+    internal uint offset;
+    internal uint lineBegin;
+    internal uint lineEnd;
+    internal ushort colBegin;
+    internal ushort colEnd;
+
+    internal PdbLine(uint offset, uint lineBegin, ushort colBegin, uint lineEnd, ushort colEnd) {
+      this.offset = offset;
+      this.lineBegin = lineBegin;
+      this.colBegin = colBegin;
+      this.lineEnd = lineEnd;
+      this.colEnd = colEnd;
+    }
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLine.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 71c64f8ac3d0fe243b55a593a5414e81
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 23 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLines.cs

@@ -0,0 +1,23 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal class PdbLines {
+    internal PdbSource file;
+    internal PdbLine[] lines;
+
+    internal PdbLines(PdbSource file, uint count) {
+      this.file = file;
+      this.lines = new PdbLine[count];
+    }
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLines.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0eced0407e6419d43b2e57c7af03e950
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 40 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbReader.cs

@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+using System.IO;
+
+namespace Microsoft.Cci.Pdb {
+  internal class PdbReader {
+    internal PdbReader(Stream reader, int pageSize) {
+      this.pageSize = pageSize;
+      this.reader = reader;
+    }
+
+    internal void Seek(int page, int offset) {
+      reader.Seek(page * pageSize + offset, SeekOrigin.Begin);
+    }
+
+    internal void Read(byte[] bytes, int offset, int count) {
+      reader.Read(bytes, offset, count);
+    }
+
+    internal int PagesFromSize(int size) {
+      return (size + pageSize - 1) / (pageSize);
+    }
+
+    //internal int PageSize {
+    //  get { return pageSize; }
+    //}
+
+    internal readonly int pageSize;
+    internal readonly Stream reader;
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbReader.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 9ff818a6b949cb040853570dab0bf370
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 122 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbScope.cs

@@ -0,0 +1,122 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal class PdbScope {
+    internal PdbConstant[] constants;
+    internal PdbSlot[] slots;
+    internal PdbScope[] scopes;
+    internal string[] usedNamespaces;
+
+    //internal uint segment;
+    internal uint address;
+    internal uint offset;
+    internal uint length;
+
+    internal PdbScope(uint address, uint length, PdbSlot[] slots, PdbConstant[] constants, string[] usedNamespaces) {
+      this.constants = constants;
+      this.slots = slots;
+      this.scopes = new PdbScope[0];
+      this.usedNamespaces = usedNamespaces;
+      this.address = address;
+      this.offset = 0;
+      this.length = length;
+    }
+
+    internal PdbScope(uint funcOffset, BlockSym32 block, BitAccess bits, out uint typind) {
+      //this.segment = block.seg;
+      this.address = block.off;
+      this.offset = block.off - funcOffset;
+      this.length = block.len;
+      typind = 0;
+
+      int constantCount;
+      int scopeCount;
+      int slotCount;
+      int namespaceCount;
+      PdbFunction.CountScopesAndSlots(bits, block.end, out constantCount, out scopeCount, out slotCount, out namespaceCount);
+      constants = new PdbConstant[constantCount];
+      scopes = new PdbScope[scopeCount];
+      slots = new PdbSlot[slotCount];
+      usedNamespaces = new string[namespaceCount];
+      int constant = 0;
+      int scope = 0;
+      int slot = 0;
+      int usedNs = 0;
+
+      while (bits.Position < block.end) {
+        ushort siz;
+        ushort rec;
+
+        bits.ReadUInt16(out siz);
+        int star = bits.Position;
+        int stop = bits.Position + siz;
+        bits.Position = star;
+        bits.ReadUInt16(out rec);
+
+        switch ((SYM)rec) {
+          case SYM.S_BLOCK32: {
+              BlockSym32 sub = new BlockSym32();
+
+              bits.ReadUInt32(out sub.parent);
+              bits.ReadUInt32(out sub.end);
+              bits.ReadUInt32(out sub.len);
+              bits.ReadUInt32(out sub.off);
+              bits.ReadUInt16(out sub.seg);
+              bits.SkipCString(out sub.name);
+
+              bits.Position = stop;
+              scopes[scope++] = new PdbScope(funcOffset, sub, bits, out typind);
+              break;
+            }
+
+          case SYM.S_MANSLOT:
+            slots[slot++] = new PdbSlot(bits, out typind);
+            bits.Position = stop;
+            break;
+
+          case SYM.S_UNAMESPACE:
+            bits.ReadCString(out usedNamespaces[usedNs++]);
+            bits.Position = stop;
+            break;
+
+          case SYM.S_END:
+            bits.Position = stop;
+            break;
+
+          case SYM.S_MANCONSTANT:
+            constants[constant++] = new PdbConstant(bits);
+            bits.Position = stop;
+            break;
+
+          default:
+            //throw new PdbException("Unknown SYM in scope {0}", (SYM)rec);
+            bits.Position = stop;
+            break;
+        }
+      }
+
+      if (bits.Position != block.end) {
+        throw new Exception("Not at S_END");
+      }
+
+      ushort esiz;
+      ushort erec;
+      bits.ReadUInt16(out esiz);
+      bits.ReadUInt16(out erec);
+
+      if (erec != (ushort)SYM.S_END) {
+        throw new Exception("Missing S_END");
+      }
+    }
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbScope.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 58146078fca58ab459dc9c80a744ecad
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 40 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSlot.cs

@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal class PdbSlot {
+    internal uint slot;
+    internal string name;
+    internal ushort flags;
+    //internal uint segment;
+    //internal uint address;
+
+    internal PdbSlot(BitAccess bits, out uint typind) {
+      AttrSlotSym slot;
+
+      bits.ReadUInt32(out slot.index);
+      bits.ReadUInt32(out slot.typind);
+      bits.ReadUInt32(out slot.offCod);
+      bits.ReadUInt16(out slot.segCod);
+      bits.ReadUInt16(out slot.flags);
+      bits.ReadCString(out slot.name);
+
+      this.slot = slot.index;
+      this.name = slot.name;
+      this.flags = slot.flags;
+      //this.segment = slot.segCod;
+      //this.address = slot.offCod;
+
+      typind = slot.typind;
+    }
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSlot.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c4fe2d82f0436ad43877b4412e548e41
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 29 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSource.cs

@@ -0,0 +1,29 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//-----------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Cci.Pdb {
+  internal class PdbSource {
+    //internal uint index;
+    internal string name;
+    internal Guid doctype;
+    internal Guid language;
+    internal Guid vendor;
+
+    internal PdbSource(/*uint index, */string name, Guid doctype, Guid language, Guid vendor) {
+      //this.index = index;
+      this.name = name;
+      this.doctype = doctype;
+      this.language = language;
+      this.vendor = vendor;
+    }
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSource.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3f3bb4d9ae4de4f4f958fdd090d83757
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 33 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs

@@ -0,0 +1,33 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (C) Microsoft Corporation.  All Rights Reserved.
+//
+//-----------------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Microsoft.Cci;
+using Microsoft.Cci.Pdb;
+using System.Text;
+using System.Diagnostics.SymbolStore;
+
+namespace Microsoft.Cci {
+
+  internal sealed class PdbIteratorScope : ILocalScope {
+
+    internal PdbIteratorScope(uint offset, uint length) {
+      this.offset = offset;
+      this.length = length;
+    }
+
+    public uint Offset {
+      get { return this.offset; }
+    }
+    uint offset;
+
+    public uint Length {
+      get { return this.length; }
+    }
+    uint length;
+  }
+}

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3ad5a79c98b198b42a20622526fe93e6
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 5 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: ddc853d849f987948ab3f6193792c793
+folderAsset: yes
+DefaultImporter:
+  userData: 

+ 41 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs

@@ -0,0 +1,41 @@
+// ISymUnmanagedDocumentWriter.cs
+//
+// Author:
+//   Juerg Billeter (j@bitron.ch)
+//
+// (C) 2008 Juerg Billeter
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System.Runtime.InteropServices;
+
+#if CANWRITE
+
+namespace Mono.Cecil.Pdb {
+
+	[Guid ("B01FAFEB-C450-3A4D-BEEC-B4CEEC01E006")]
+	[InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
+	[ComImport]
+	interface ISymUnmanagedDocumentWriter {
+	}
+}
+
+#endif

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 09cc940ff93c54e498983384a765d014
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 103 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs

@@ -0,0 +1,103 @@
+//
+// ISymUnmanagedWriter2.cs
+//
+// Author:
+//   Juerg Billeter (j@bitron.ch)
+//
+// (C) 2008 Juerg Billeter
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Diagnostics.SymbolStore;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.ComTypes;
+
+using Mono.Cecil.Cil;
+
+#if CANWRITE
+
+namespace Mono.Cecil.Pdb {
+
+	[Guid ("0B97726E-9E6D-4f05-9A26-424022093CAA")]
+	[InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
+	[ComImport]
+	interface ISymUnmanagedWriter2 {
+
+		void DefineDocument (
+			[In, MarshalAs (UnmanagedType.LPWStr)] string url,
+			[In] ref Guid langauge,
+			[In] ref Guid languageVendor,
+			[In] ref Guid documentType,
+			[Out, MarshalAs (UnmanagedType.Interface)] out ISymUnmanagedDocumentWriter pRetVal);
+		void SetUserEntryPoint ([In] SymbolToken method);
+		void OpenMethod ([In] SymbolToken method);
+		void CloseMethod ();
+		void OpenScope ([In] int startOffset, [Out] out int pRetVal);
+		void CloseScope ([In] int endOffset);
+		void SetScopeRange_Placeholder ();
+		void DefineLocalVariable_Placeholder ();
+		void DefineParameter_Placeholder ();
+		void DefineField_Placeholder ();
+		void DefineGlobalVariable_Placeholder ();
+		void Close ();
+		void SetSymAttribute_Placeholder ();
+		void OpenNamespace ([In, MarshalAs (UnmanagedType.LPWStr)] string name);
+		void CloseNamespace ();
+		void UsingNamespace ([In, MarshalAs (UnmanagedType.LPWStr)] string fullName);
+		void SetMethodSourceRange_Placeholder ();
+		void Initialize (
+			[In, MarshalAs (UnmanagedType.IUnknown)] object emitter,
+			[In, MarshalAs (UnmanagedType.LPWStr)] string filename,
+			[In] IStream pIStream,
+			[In] bool fFullBuild);
+		void GetDebugInfo (
+			[Out] out ImageDebugDirectory pIDD,
+			[In] int cData,
+			[Out] out int pcData,
+			[In, Out, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] byte [] data);
+		void DefineSequencePoints (
+			[In, MarshalAs (UnmanagedType.Interface)] ISymUnmanagedDocumentWriter document,
+			[In] int spCount,
+			[In, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] int [] offsets,
+			[In, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] int [] lines,
+			[In, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] int [] columns,
+			[In, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] int [] endLines,
+			[In, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] int [] endColumns);
+		void RemapToken_Placeholder ();
+		void Initialize2_Placeholder ();
+		void DefineConstant_Placeholder ();
+		void Abort_Placeholder ();
+
+		void DefineLocalVariable2 (
+			[In, MarshalAs (UnmanagedType.LPWStr)] string name,
+			[In] int attributes,
+			[In] SymbolToken sigToken,
+			[In] int addrKind,
+			[In] int addr1,
+			[In] int addr2,
+			[In] int addr3,
+			[In] int startOffset,
+			[In] int endOffset);
+	}
+}
+
+#endif

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 5cfa1a4fe33940245877fa4bc038ffcb
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 796 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ModuleMetadata.cs

@@ -0,0 +1,796 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+
+#if CANWRITE
+
+namespace Mono.Cecil.Pdb {
+
+	[ComImport, InterfaceType (ComInterfaceType.InterfaceIsIUnknown), Guid ("BA3FEE4C-ECB9-4e41-83B7-183FA41CD859")]
+	interface IMetaDataEmit {
+		void SetModuleProps (string szName);
+		void Save (string szFile, uint dwSaveFlags);
+		void SaveToStream (IntPtr pIStream, uint dwSaveFlags);
+		uint GetSaveSize (uint fSave);
+		uint DefineTypeDef (IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements);
+		uint DefineNestedType (IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements, uint tdEncloser);
+		void SetHandler ([MarshalAs (UnmanagedType.IUnknown), In]object pUnk);
+		uint DefineMethod (uint td, IntPtr zName, uint dwMethodFlags, IntPtr pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags);
+		void DefineMethodImpl (uint td, uint tkBody, uint tkDecl);
+		uint DefineTypeRefByName (uint tkResolutionScope, IntPtr szName);
+		uint DefineImportType (IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport,
+		  uint tdImport, IntPtr pAssemEmit);
+		uint DefineMemberRef (uint tkImport, string szName, IntPtr pvSigBlob, uint cbSigBlob);
+		uint DefineImportMember (IntPtr pAssemImport, IntPtr /* void* */ pbHashValue, uint cbHashValue,
+		  IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent);
+		uint DefineEvent (uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr /* uint* */ rmdOtherMethods);
+		void SetClassLayout (uint td, uint dwPackSize, IntPtr /*COR_FIELD_OFFSET**/ rFieldOffsets, uint ulClassSize);
+		void DeleteClassLayout (uint td);
+		void SetFieldMarshal (uint tk, IntPtr /* byte* */ pvNativeType, uint cbNativeType);
+		void DeleteFieldMarshal (uint tk);
+		uint DefinePermissionSet (uint tk, uint dwAction, IntPtr /* void* */ pvPermission, uint cbPermission);
+		void SetRVA (uint md, uint ulRVA);
+		uint GetTokenFromSig (IntPtr /* byte* */ pvSig, uint cbSig);
+		uint DefineModuleRef (string szName);
+		void SetParent (uint mr, uint tk);
+		uint GetTokenFromTypeSpec (IntPtr /* byte* */ pvSig, uint cbSig);
+		void SaveToMemory (IntPtr /* void* */ pbData, uint cbData);
+		uint DefineUserString (string szString, uint cchString);
+		void DeleteToken (uint tkObj);
+		void SetMethodProps (uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags);
+		void SetTypeDefProps (uint td, uint dwTypeDefFlags, uint tkExtends, IntPtr /* uint* */ rtkImplements);
+		void SetEventProps (uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr /* uint* */ rmdOtherMethods);
+		uint SetPermissionSetProps (uint tk, uint dwAction, IntPtr /* void* */ pvPermission, uint cbPermission);
+		void DefinePinvokeMap (uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL);
+		void SetPinvokeMap (uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL);
+		void DeletePinvokeMap (uint tk);
+		uint DefineCustomAttribute (uint tkObj, uint tkType, IntPtr /* void* */ pCustomAttribute, uint cbCustomAttribute);
+		void SetCustomAttributeValue (uint pcv, IntPtr /* void* */ pCustomAttribute, uint cbCustomAttribute);
+		uint DefineField (uint td, string szName, uint dwFieldFlags, IntPtr /* byte* */ pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag, IntPtr /* void* */ pValue, uint cchValue);
+		uint DefineProperty (uint td, string szProperty, uint dwPropFlags, IntPtr /* byte* */ pvSig, uint cbSig, uint dwCPlusTypeFlag,
+		  IntPtr /* void* */ pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr /* uint*  */ rmdOtherMethods);
+		uint DefineParam (uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr /* void* */ pValue, uint cchValue);
+		void SetFieldProps (uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, IntPtr /* void* */ pValue, uint cchValue);
+		void SetPropertyProps (uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, IntPtr /* void* */ pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr /* uint* */ rmdOtherMethods);
+		void SetParamProps (uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr /* void* */ pValue, uint cchValue);
+		uint DefineSecurityAttributeSet (uint tkObj, IntPtr rSecAttrs, uint cSecAttrs);
+		void ApplyEditAndContinue ([MarshalAs (UnmanagedType.IUnknown)]object pImport);
+		uint TranslateSigWithScope (IntPtr pAssemImport, IntPtr /* void* */ pbHashValue, uint cbHashValue,
+		  IMetaDataImport import, IntPtr /* byte* */ pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, IntPtr /* byte* */ pvTranslatedSig, uint cbTranslatedSigMax);
+		void SetMethodImplFlags (uint md, uint dwImplFlags);
+		void SetFieldRVA (uint fd, uint ulRVA);
+		void Merge (IMetaDataImport pImport, IntPtr pHostMapToken, [MarshalAs (UnmanagedType.IUnknown)]object pHandler);
+		void MergeEnd ();
+	}
+
+	[ComImport, InterfaceType (ComInterfaceType.InterfaceIsIUnknown), Guid ("7DAC8207-D3AE-4c75-9B67-92801A497D44")]
+	interface IMetaDataImport {
+		[PreserveSig]
+		void CloseEnum (uint hEnum);
+		uint CountEnum (uint hEnum);
+		void ResetEnum (uint hEnum, uint ulPos);
+		uint EnumTypeDefs (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rTypeDefs, uint cMax);
+		uint EnumInterfaceImpls (ref uint phEnum, uint td, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] uint [] rImpls, uint cMax);
+		uint EnumTypeRefs (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rTypeRefs, uint cMax);
+		uint FindTypeDefByName (string szTypeDef, uint tkEnclosingClass);
+		Guid GetScopeProps (StringBuilder szName, uint cchName, out uint pchName);
+		uint GetModuleFromScope ();
+		uint GetTypeDefProps (uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags);
+		uint GetInterfaceImplProps (uint iiImpl, out uint pClass);
+		uint GetTypeRefProps (uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName);
+		uint ResolveTypeRef (uint tr, [In] ref Guid riid, [MarshalAs (UnmanagedType.Interface)] out object ppIScope);
+		uint EnumMembers (ref uint phEnum, uint cl, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] uint [] rMembers, uint cMax);
+		uint EnumMembersWithName (ref uint phEnum, uint cl, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rMembers, uint cMax);
+		uint EnumMethods (ref uint phEnum, uint cl, IntPtr /* uint* */ rMethods, uint cMax);
+		uint EnumMethodsWithName (ref uint phEnum, uint cl, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rMethods, uint cMax);
+		uint EnumFields (ref uint phEnum, uint cl, IntPtr /* uint* */ rFields, uint cMax);
+		uint EnumFieldsWithName (ref uint phEnum, uint cl, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rFields, uint cMax);
+		uint EnumParams (ref uint phEnum, uint mb, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] uint [] rParams, uint cMax);
+		uint EnumMemberRefs (ref uint phEnum, uint tkParent, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] uint [] rMemberRefs, uint cMax);
+		uint EnumMethodImpls (ref uint phEnum, uint td, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rMethodBody,
+		   [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rMethodDecl, uint cMax);
+		uint EnumPermissionSets (ref uint phEnum, uint tk, uint dwActions, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rPermission,
+		   uint cMax);
+		uint FindMember (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob);
+		uint FindMethod (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob);
+		uint FindField (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob);
+		uint FindMemberRef (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob);
+		uint GetMethodProps (uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA);
+		uint GetMemberRefProps (uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr /* byte* */ ppvSigBlob);
+		uint EnumProperties (ref uint phEnum, uint td, IntPtr /* uint* */ rProperties, uint cMax);
+		uint EnumEvents (ref uint phEnum, uint td, IntPtr /* uint* */ rEvents, uint cMax);
+		uint GetEventProps (uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags,
+		  out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire,
+		  [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 11)] uint [] rmdOtherMethod, uint cMax);
+		uint EnumMethodSemantics (ref uint phEnum, uint mb, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] uint [] rEventProp, uint cMax);
+		uint GetMethodSemantics (uint mb, uint tkEventProp);
+		uint GetClassLayout (uint td, out uint pdwPackSize, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] IntPtr /*COR_FIELD_OFFSET **/ rFieldOffset, uint cMax, out uint pcFieldOffset);
+		uint GetFieldMarshal (uint tk, out IntPtr /* byte* */ ppvNativeType);
+		uint GetRVA (uint tk, out uint pulCodeRVA);
+		uint GetPermissionSetProps (uint pm, out uint pdwAction, out IntPtr /* void* */ ppvPermission);
+		uint GetSigFromToken (uint mdSig, out IntPtr /* byte* */ ppvSig);
+		uint GetModuleRefProps (uint mur, StringBuilder szName, uint cchName);
+		uint EnumModuleRefs (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rModuleRefs, uint cmax);
+		uint GetTypeSpecFromToken (uint typespec, out IntPtr /* byte* */ ppvSig);
+		uint GetNameFromToken (uint tk);
+		uint EnumUnresolvedMethods (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rMethods, uint cMax);
+		uint GetUserString (uint stk, StringBuilder szString, uint cchString);
+		uint GetPinvokeMap (uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName);
+		uint EnumSignatures (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rSignatures, uint cmax);
+		uint EnumTypeSpecs (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rTypeSpecs, uint cmax);
+		uint EnumUserStrings (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rStrings, uint cmax);
+		[PreserveSig]
+		int GetParamForMethodIndex (uint md, uint ulParamSeq, out uint pParam);
+		uint EnumCustomAttributes (ref uint phEnum, uint tk, uint tkType, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rCustomAttributes, uint cMax);
+		uint GetCustomAttributeProps (uint cv, out uint ptkObj, out uint ptkType, out IntPtr /* void* */ ppBlob);
+		uint FindTypeRef (uint tkResolutionScope, string szName);
+		uint GetMemberProps (uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr,
+		  out IntPtr /* byte* */ ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr /* void* */ ppValue);
+		uint GetFieldProps (uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr,
+		  out IntPtr /* byte* */ ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr /* void* */ ppValue);
+		uint GetPropertyProps (uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags,
+		  out IntPtr /* byte* */ ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr /* void* */ ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter,
+		  out uint pmdGetter, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 14)] uint [] rmdOtherMethod, uint cMax);
+		uint GetParamProps (uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName,
+		  out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr /* void* */ ppValue);
+		uint GetCustomAttributeByName (uint tkObj, string szName, out IntPtr /* void* */ ppData);
+		[PreserveSig]
+		[return: MarshalAs (UnmanagedType.Bool)]
+		bool IsValidToken (uint tk);
+		uint GetNestedClassProps (uint tdNestedClass);
+		uint GetNativeCallConvFromSig (IntPtr /* void* */ pvSig, uint cbSig);
+		int IsGlobal (uint pd);
+	}
+
+	class ModuleMetadata : IMetaDataEmit, IMetaDataImport {
+
+		readonly ModuleDefinition module;
+
+		Dictionary<uint, TypeDefinition> types;
+		Dictionary<uint, MethodDefinition> methods;
+
+		public ModuleMetadata (ModuleDefinition module)
+		{
+			this.module = module;
+		}
+
+		bool TryGetType (uint token, out TypeDefinition type)
+		{
+			if (types == null)
+				InitializeMetadata (module);
+
+			return types.TryGetValue (token, out type);
+		}
+
+		bool TryGetMethod (uint token, out MethodDefinition method)
+		{
+			if (methods == null)
+				InitializeMetadata (module);
+
+			return methods.TryGetValue (token, out method);
+		}
+
+		void InitializeMetadata (ModuleDefinition module)
+		{
+			types = new Dictionary<uint, TypeDefinition> ();
+			methods = new Dictionary<uint, MethodDefinition> ();
+
+			foreach (var type in module.GetTypes ()) {
+				types.Add (type.MetadataToken.ToUInt32 (), type);
+				InitializeMethods (type);
+			}
+		}
+
+		void InitializeMethods (TypeDefinition type)
+		{
+			foreach (var method in type.Methods)
+				methods.Add (method.MetadataToken.ToUInt32 (), method);
+		}
+
+		public void SetModuleProps (string szName)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void Save (string szFile, uint dwSaveFlags)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SaveToStream (IntPtr pIStream, uint dwSaveFlags)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetSaveSize (uint fSave)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineTypeDef (IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineNestedType (IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements, uint tdEncloser)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetHandler (object pUnk)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineMethod (uint td, IntPtr zName, uint dwMethodFlags, IntPtr pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void DefineMethodImpl (uint td, uint tkBody, uint tkDecl)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineTypeRefByName (uint tkResolutionScope, IntPtr szName)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineImportType (IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint tdImport, IntPtr pAssemEmit)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineMemberRef (uint tkImport, string szName, IntPtr pvSigBlob, uint cbSigBlob)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineImportMember (IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineEvent (uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetClassLayout (uint td, uint dwPackSize, IntPtr rFieldOffsets, uint ulClassSize)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void DeleteClassLayout (uint td)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetFieldMarshal (uint tk, IntPtr pvNativeType, uint cbNativeType)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void DeleteFieldMarshal (uint tk)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefinePermissionSet (uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetRVA (uint md, uint ulRVA)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetTokenFromSig (IntPtr pvSig, uint cbSig)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineModuleRef (string szName)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetParent (uint mr, uint tk)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetTokenFromTypeSpec (IntPtr pvSig, uint cbSig)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SaveToMemory (IntPtr pbData, uint cbData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineUserString (string szString, uint cchString)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void DeleteToken (uint tkObj)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetMethodProps (uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetTypeDefProps (uint td, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetEventProps (uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint SetPermissionSetProps (uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void DefinePinvokeMap (uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetPinvokeMap (uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void DeletePinvokeMap (uint tk)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineCustomAttribute (uint tkObj, uint tkType, IntPtr pCustomAttribute, uint cbCustomAttribute)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetCustomAttributeValue (uint pcv, IntPtr pCustomAttribute, uint cbCustomAttribute)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineField (uint td, string szName, uint dwFieldFlags, IntPtr pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineProperty (uint td, string szProperty, uint dwPropFlags, IntPtr pvSig, uint cbSig, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineParam (uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetFieldProps (uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetPropertyProps (uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetParamProps (uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint DefineSecurityAttributeSet (uint tkObj, IntPtr rSecAttrs, uint cSecAttrs)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void ApplyEditAndContinue (object pImport)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint TranslateSigWithScope (IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport import, IntPtr pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, IntPtr pvTranslatedSig, uint cbTranslatedSigMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetMethodImplFlags (uint md, uint dwImplFlags)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void SetFieldRVA (uint fd, uint ulRVA)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void Merge (IMetaDataImport pImport, IntPtr pHostMapToken, object pHandler)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void MergeEnd ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void CloseEnum (uint hEnum)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint CountEnum (uint hEnum)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void ResetEnum (uint hEnum, uint ulPos)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumTypeDefs (ref uint phEnum, uint[] rTypeDefs, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumInterfaceImpls (ref uint phEnum, uint td, uint[] rImpls, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumTypeRefs (ref uint phEnum, uint[] rTypeRefs, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint FindTypeDefByName (string szTypeDef, uint tkEnclosingClass)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public Guid GetScopeProps (StringBuilder szName, uint cchName, out uint pchName)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetModuleFromScope ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetTypeDefProps (uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags)
+		{
+			TypeDefinition type;
+			if (!TryGetType (td, out type)) {
+				Marshal.WriteInt16 (szTypeDef, 0);
+				pchTypeDef = 1;
+				return 0;
+			}
+
+			WriteString (type.Name, szTypeDef, cchTypeDef, out pchTypeDef);
+			WriteIntPtr (pdwTypeDefFlags, (uint) type.Attributes);
+			return type.BaseType != null ? type.BaseType.MetadataToken.ToUInt32 () : 0;
+		}
+
+		static void WriteIntPtr (IntPtr ptr, uint value)
+		{
+			if (ptr == IntPtr.Zero)
+				return;
+
+			Marshal.WriteInt32 (ptr, (int) value);
+		}
+
+		static void WriteString (string str, IntPtr buffer, uint bufferSize, out uint chars)
+		{
+			var length = str.Length + 1 >= bufferSize ? bufferSize - 1 : (uint) str.Length;
+			chars = length + 1;
+			var offset = 0;
+
+			for (int i = 0; i < length; i++) {
+				Marshal.WriteInt16 (buffer, offset, str [i]);
+				offset += 2;
+			}
+
+			Marshal.WriteInt16 (buffer, offset, 0);
+		}
+
+		public uint GetInterfaceImplProps (uint iiImpl, out uint pClass)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetTypeRefProps (uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint ResolveTypeRef (uint tr, ref Guid riid, out object ppIScope)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumMembers (ref uint phEnum, uint cl, uint[] rMembers, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumMembersWithName (ref uint phEnum, uint cl, string szName, uint[] rMembers, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumMethods (ref uint phEnum, uint cl, IntPtr rMethods, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumMethodsWithName (ref uint phEnum, uint cl, string szName, uint[] rMethods, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumFields (ref uint phEnum, uint cl, IntPtr rFields, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumFieldsWithName (ref uint phEnum, uint cl, string szName, uint[] rFields, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumParams (ref uint phEnum, uint mb, uint[] rParams, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumMemberRefs (ref uint phEnum, uint tkParent, uint[] rMemberRefs, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumMethodImpls (ref uint phEnum, uint td, uint[] rMethodBody, uint[] rMethodDecl, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumPermissionSets (ref uint phEnum, uint tk, uint dwActions, uint[] rPermission, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint FindMember (uint td, string szName, byte[] pvSigBlob, uint cbSigBlob)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint FindMethod (uint td, string szName, byte[] pvSigBlob, uint cbSigBlob)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint FindField (uint td, string szName, byte[] pvSigBlob, uint cbSigBlob)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint FindMemberRef (uint td, string szName, byte[] pvSigBlob, uint cbSigBlob)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetMethodProps (uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA)
+		{
+			MethodDefinition method;
+			if (!TryGetMethod (mb, out method)) {
+				Marshal.WriteInt16 (szMethod, 0);
+				pchMethod = 1;
+				pClass = 0;
+				return 0;
+			}
+
+			pClass = method.DeclaringType.MetadataToken.ToUInt32 ();
+			WriteString (method.Name, szMethod, cchMethod, out pchMethod);
+			WriteIntPtr (pdwAttr, (uint) method.Attributes);
+			WriteIntPtr (pulCodeRVA, (uint) method.RVA);
+
+			return (uint) method.ImplAttributes;
+		}
+
+		public uint GetMemberRefProps (uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumProperties (ref uint phEnum, uint td, IntPtr rProperties, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumEvents (ref uint phEnum, uint td, IntPtr rEvents, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetEventProps (uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, uint[] rmdOtherMethod, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumMethodSemantics (ref uint phEnum, uint mb, uint[] rEventProp, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetMethodSemantics (uint mb, uint tkEventProp)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetClassLayout (uint td, out uint pdwPackSize, IntPtr rFieldOffset, uint cMax, out uint pcFieldOffset)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetFieldMarshal (uint tk, out IntPtr ppvNativeType)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetRVA (uint tk, out uint pulCodeRVA)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetPermissionSetProps (uint pm, out uint pdwAction, out IntPtr ppvPermission)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetSigFromToken (uint mdSig, out IntPtr ppvSig)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetModuleRefProps (uint mur, StringBuilder szName, uint cchName)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumModuleRefs (ref uint phEnum, uint[] rModuleRefs, uint cmax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetTypeSpecFromToken (uint typespec, out IntPtr ppvSig)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetNameFromToken (uint tk)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumUnresolvedMethods (ref uint phEnum, uint[] rMethods, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetUserString (uint stk, StringBuilder szString, uint cchString)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetPinvokeMap (uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumSignatures (ref uint phEnum, uint[] rSignatures, uint cmax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumTypeSpecs (ref uint phEnum, uint[] rTypeSpecs, uint cmax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumUserStrings (ref uint phEnum, uint[] rStrings, uint cmax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public int GetParamForMethodIndex (uint md, uint ulParamSeq, out uint pParam)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint EnumCustomAttributes (ref uint phEnum, uint tk, uint tkType, uint[] rCustomAttributes, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetCustomAttributeProps (uint cv, out uint ptkObj, out uint ptkType, out IntPtr ppBlob)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint FindTypeRef (uint tkResolutionScope, string szName)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetMemberProps (uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr ppValue)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetFieldProps (uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr ppValue)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetPropertyProps (uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out IntPtr ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, uint[] rmdOtherMethod, uint cMax)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetParamProps (uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr ppValue)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetCustomAttributeByName (uint tkObj, string szName, out IntPtr ppData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public bool IsValidToken (uint tk)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public uint GetNestedClassProps (uint tdNestedClass)
+		{
+			TypeDefinition type;
+			if (!TryGetType (tdNestedClass, out type))
+				return 0;
+
+			return type.IsNested ? type.DeclaringType.MetadataToken.ToUInt32 () : 0;
+		}
+
+		public uint GetNativeCallConvFromSig (IntPtr pvSig, uint cbSig)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public int IsGlobal (uint pd)
+		{
+			throw new NotImplementedException ();
+		}
+	}
+}
+
+#endif

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ModuleMetadata.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0cf63c099a48b954ea6991387d553ab6
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 196 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbHelper.cs

@@ -0,0 +1,196 @@
+//
+// PdbHelper.cs
+//
+// Author:
+//   Jb Evain (jbevain@gmail.com)
+//
+// Copyright (c) 2008 - 2011 Jb Evain
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+using Mono.Cecil.Cil;
+
+namespace Mono.Cecil.Pdb {
+
+	class PdbHelper {
+
+#if CANWRITE
+		public static SymWriter CreateWriter (ModuleDefinition module, string pdb)
+		{
+			var writer = new SymWriter ();
+
+			if (File.Exists (pdb))
+				File.Delete (pdb);
+
+			writer.Initialize (new ModuleMetadata (module), pdb, true);
+
+			return writer;
+		}
+#endif
+
+		public static string GetPdbFileName (string assemblyFileName)
+		{
+			return Path.ChangeExtension (assemblyFileName, ".pdb");
+		}
+	}
+
+	public class PdbReaderProvider : ISymbolReaderProvider {
+
+		public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
+		{
+			return new PdbReader (File.OpenRead (PdbHelper.GetPdbFileName (fileName)));
+		}
+
+		public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
+		{
+			return new PdbReader (symbolStream);
+		}
+	}
+
+#if CANWRITE
+
+	public class PdbWriterProvider : ISymbolWriterProvider {
+
+		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
+		{
+			return new PdbWriter (module, PdbHelper.CreateWriter (module, PdbHelper.GetPdbFileName (fileName)));
+		}
+
+		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
+		{
+			throw new NotImplementedException ();
+		}
+	}
+
+#endif
+
+	static class GuidMapping {
+
+		static readonly Dictionary<Guid, DocumentLanguage> guid_language = new Dictionary<Guid, DocumentLanguage> ();
+		static readonly Dictionary<DocumentLanguage, Guid> language_guid = new Dictionary<DocumentLanguage, Guid> ();
+
+		static GuidMapping ()
+		{
+			AddMapping (DocumentLanguage.C, new Guid (0x63a08714, 0xfc37, 0x11d2, 0x90, 0x4c, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1));
+			AddMapping (DocumentLanguage.Cpp, new Guid (0x3a12d0b7, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2));
+			AddMapping (DocumentLanguage.CSharp, new Guid (0x3f5162f8, 0x07c6, 0x11d3, 0x90, 0x53, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1));
+			AddMapping (DocumentLanguage.Basic, new Guid (0x3a12d0b8, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2));
+			AddMapping (DocumentLanguage.Java, new Guid (0x3a12d0b4, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2));
+			AddMapping (DocumentLanguage.Cobol, new Guid (0xaf046cd1, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc));
+			AddMapping (DocumentLanguage.Pascal, new Guid (0xaf046cd2, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc));
+			AddMapping (DocumentLanguage.Cil, new Guid (0xaf046cd3, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc));
+			AddMapping (DocumentLanguage.JScript, new Guid (0x3a12d0b6, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2));
+			AddMapping (DocumentLanguage.Smc, new Guid (0xd9b9f7b, 0x6611, 0x11d3, 0xbd, 0x2a, 0x0, 0x0, 0xf8, 0x8, 0x49, 0xbd));
+			AddMapping (DocumentLanguage.MCpp, new Guid (0x4b35fde8, 0x07c6, 0x11d3, 0x90, 0x53, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1));
+			//AddMapping (DocumentLanguage.FSharp, new Guid (0xab4f38c9, 0xb6e6, 0x43ba, 0xbe, 0x3b, 0x58, 0x08, 0x0b, 0x2c, 0xcc, 0xe3));
+		}
+
+		static void AddMapping (DocumentLanguage language, Guid guid)
+		{
+			guid_language.Add (guid, language);
+			language_guid.Add (language, guid);
+		}
+
+		static readonly Guid type_text = new Guid (0x5a869d0b, 0x6611, 0x11d3, 0xbd, 0x2a, 0x00, 0x00, 0xf8, 0x08, 0x49, 0xbd);
+
+		public static DocumentType ToType (this Guid guid)
+		{
+			if (guid == type_text)
+				return DocumentType.Text;
+
+			return DocumentType.Other;
+		}
+
+		public static Guid ToGuid (this DocumentType type)
+		{
+			if (type == DocumentType.Text)
+				return type_text;
+
+			return new Guid ();
+		}
+
+		static readonly Guid hash_md5 = new Guid (0x406ea660, 0x64cf, 0x4c82, 0xb6, 0xf0, 0x42, 0xd4, 0x81, 0x72, 0xa7, 0x99);
+		static readonly Guid hash_sha1 = new Guid (0xff1816ec, 0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60);
+
+		public static DocumentHashAlgorithm ToHashAlgorithm (this Guid guid)
+		{
+			if (guid == hash_md5)
+				return DocumentHashAlgorithm.MD5;
+
+			if (guid == hash_sha1)
+				return DocumentHashAlgorithm.SHA1;
+
+			return DocumentHashAlgorithm.None;
+		}
+
+		public static Guid ToGuid (this DocumentHashAlgorithm hash_algo)
+		{
+			if (hash_algo == DocumentHashAlgorithm.MD5)
+				return hash_md5;
+
+			if (hash_algo == DocumentHashAlgorithm.SHA1)
+				return hash_sha1;
+
+			return new Guid ();
+		}
+
+		public static DocumentLanguage ToLanguage (this Guid guid)
+		{
+			DocumentLanguage language;
+			if (!guid_language.TryGetValue (guid, out language))
+				return DocumentLanguage.Other;
+
+			return language;
+		}
+
+		public static Guid ToGuid (this DocumentLanguage language)
+		{
+			Guid guid;
+			if (!language_guid.TryGetValue (language, out guid))
+				return new Guid ();
+
+			return guid;
+		}
+
+		static readonly Guid vendor_ms = new Guid (0x994b45c4, 0xe6e9, 0x11d2, 0x90, 0x3f, 0x00, 0xc0, 0x4f, 0xa3, 0x02, 0xa1);
+
+		public static DocumentLanguageVendor ToVendor (this Guid guid)
+		{
+			if (guid == vendor_ms)
+				return DocumentLanguageVendor.Microsoft;
+
+			return DocumentLanguageVendor.Other;
+		}
+
+		public static Guid ToGuid (this DocumentLanguageVendor vendor)
+		{
+			if (vendor == DocumentLanguageVendor.Microsoft)
+				return vendor_ms;
+
+			return new Guid ();
+		}
+	}
+}
+

+ 8 - 0
Unity/Assets/Plugins/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbHelper.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bf8731a3219f7e94c8cc7f1fa008fb14
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

Некоторые файлы не были показаны из-за большого количества измененных файлов