PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody body, SymbolScope symScope) { if (symScope == null) { return(null); } // Don't use recursive calls var stack = new Stack <CreateScopeState>(); var state = new CreateScopeState() { SymScope = symScope }; recursive_call: int instrIndex = 0; int endIsInclusiveValue = Compiler == Compiler.VisualBasic ? 1 : 0; state.PdbScope = new PdbScope() { Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex), End = GetInstruction(body.Instructions, state.SymScope.EndOffset + endIsInclusiveValue, ref instrIndex), }; foreach (var cdi in state.SymScope.CustomDebugInfos) { state.PdbScope.CustomDebugInfos.Add(cdi); } foreach (var symLocal in state.SymScope.Locals) { int localIndex = symLocal.Index; if ((uint)localIndex >= (uint)body.Variables.Count) { // VB sometimes creates a PDB local without a metadata local continue; } var local = body.Variables[localIndex]; var name = symLocal.Name; local.SetName(name); var attributes = symLocal.Attributes; local.SetAttributes(attributes); var pdbLocal = new PdbLocal(local, name, attributes); foreach (var cdi in symLocal.CustomDebugInfos) { pdbLocal.CustomDebugInfos.Add(cdi); } state.PdbScope.Variables.Add(pdbLocal); } foreach (var ns in state.SymScope.Namespaces) { state.PdbScope.Namespaces.Add(ns.Name); } state.PdbScope.ImportScope = state.SymScope.ImportScope; var constants = state.SymScope.GetConstants(module, gpContext); for (int i = 0; i < constants.Count; i++) { var constant = constants[i]; var type = constant.Type.RemovePinnedAndModifiers(); if (type != null) { // Fix a few values since they're stored as some other type in the PDB switch (type.ElementType) { case ElementType.Boolean: if (constant.Value is short) { constant.Value = (short)constant.Value != 0; } break; case ElementType.Char: if (constant.Value is ushort) { constant.Value = (char)(ushort)constant.Value; } break; case ElementType.I1: if (constant.Value is short) { constant.Value = (sbyte)(short)constant.Value; } break; case ElementType.U1: if (constant.Value is short) { constant.Value = (byte)(short)constant.Value; } break; case ElementType.I2: case ElementType.U2: case ElementType.I4: case ElementType.U4: case ElementType.I8: case ElementType.U8: case ElementType.R4: case ElementType.R8: case ElementType.Void: case ElementType.Ptr: case ElementType.ByRef: case ElementType.TypedByRef: case ElementType.I: case ElementType.U: case ElementType.FnPtr: case ElementType.ValueType: break; case ElementType.String: // "" is stored as null, and null is stored as (int)0 if (constant.Value is int && (int)constant.Value == 0) { constant.Value = null; } else if (constant.Value == null) { constant.Value = string.Empty; } break; case ElementType.Object: case ElementType.Class: case ElementType.SZArray: case ElementType.Array: default: if (constant.Value is int && (int)constant.Value == 0) { constant.Value = null; } break; case ElementType.GenericInst: var gis = (GenericInstSig)type; if (gis.GenericType is ValueTypeSig) { break; } goto case ElementType.Class; case ElementType.Var: case ElementType.MVar: var gp = ((GenericSig)type).GenericParam; if (gp != null) { if (gp.HasNotNullableValueTypeConstraint) { break; } if (gp.HasReferenceTypeConstraint) { goto case ElementType.Class; } } break; } } state.PdbScope.Constants.Add(constant); } // Here's the now somewhat obfuscated for loop state.ChildrenIndex = 0; state.Children = state.SymScope.Children; do_return: if (state.ChildrenIndex < state.Children.Count) { var child = state.Children[state.ChildrenIndex]; stack.Push(state); state = new CreateScopeState() { SymScope = child }; goto recursive_call; } if (stack.Count == 0) { return(state.PdbScope); } // Return from recursive call, and execute the last part of the for loop var newPdbScope = state.PdbScope; state = stack.Pop(); state.PdbScope.Scopes.Add(newPdbScope); state.ChildrenIndex++; goto do_return; }
static PdbScope CreateScope(CilBody body, ISymbolScope symScope) { if (symScope == null) { return(null); } // Don't use recursive calls var stack = new Stack <CreateScopeState>(); var state = new CreateScopeState() { SymScope = symScope }; recursive_call: int instrIndex = 0; state.PdbScope = new PdbScope() { Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex), End = GetInstruction(body.Instructions, state.SymScope.EndOffset, ref instrIndex), }; foreach (var symLocal in state.SymScope.GetLocals()) { if (symLocal.AddressKind != SymAddressKind.ILOffset) { continue; } int localIndex = symLocal.AddressField1; if ((uint)localIndex >= (uint)body.Variables.Count) { continue; } var local = body.Variables[localIndex]; local.Name = symLocal.Name; var attributes = symLocal.Attributes; if (attributes is int) { local.PdbAttributes = (int)attributes; } state.PdbScope.Variables.Add(local); } foreach (var ns in state.SymScope.GetNamespaces()) { state.PdbScope.Namespaces.Add(ns.Name); } // Here's the now somewhat obfuscated for loop state.ChildrenIndex = 0; state.Children = state.SymScope.GetChildren(); do_return: if (state.ChildrenIndex < state.Children.Length) { var child = state.Children[state.ChildrenIndex]; stack.Push(state); state = new CreateScopeState() { SymScope = child }; goto recursive_call; } if (stack.Count == 0) { return(state.PdbScope); } // Return from recursive call, and execute the last part of the for loop var newPdbScope = state.PdbScope; state = stack.Pop(); state.PdbScope.Scopes.Add(newPdbScope); state.ChildrenIndex++; goto do_return; }
static PdbScope CreateScope(CilBody body, ISymbolScope symScope) { if (symScope == null) return null; // Don't use recursive calls var stack = new Stack<CreateScopeState>(); var state = new CreateScopeState() { SymScope = symScope }; recursive_call: int instrIndex = 0; state.PdbScope = new PdbScope() { Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex), End = GetInstruction(body.Instructions, state.SymScope.EndOffset, ref instrIndex), }; foreach (var symLocal in state.SymScope.GetLocals()) { if (symLocal.AddressKind != SymAddressKind.ILOffset) continue; int localIndex = symLocal.AddressField1; if ((uint)localIndex >= (uint)body.Variables.Count) continue; var local = body.Variables[localIndex]; local.Name = symLocal.Name; var attributes = symLocal.Attributes; if (attributes is int) local.PdbAttributes = (int)attributes; state.PdbScope.Variables.Add(local); } foreach (var ns in state.SymScope.GetNamespaces()) state.PdbScope.Namespaces.Add(ns.Name); // Here's the now somewhat obfuscated for loop state.ChildrenIndex = 0; state.Children = state.SymScope.GetChildren(); do_return: if (state.ChildrenIndex < state.Children.Length) { var child = state.Children[state.ChildrenIndex]; stack.Push(state); state = new CreateScopeState() { SymScope = child }; goto recursive_call; } if (stack.Count == 0) return state.PdbScope; // Return from recursive call, and execute the last part of the for loop var newPdbScope = state.PdbScope; state = stack.Pop(); state.PdbScope.Scopes.Add(newPdbScope); state.ChildrenIndex++; goto do_return; }