internal void EmitScopeTree(ISymbolWriter symWriter) { for (int i = 0; i < this.m_iCount; i++) { if (this.m_ScopeActions[i] == ScopeAction.Open) { symWriter.OpenScope(this.m_iOffsets[i]); } else { symWriter.CloseScope(this.m_iOffsets[i]); } if (this.m_localSymInfos[i] != null) { this.m_localSymInfos[i].EmitLocalSymInfo(symWriter); } } }
/********************************************** * Sets the IL of the method. An ILGenerator is passed as an argument and the method * queries this instance to get all of the information which it needs. * @param il An ILGenerator with some il defined. * @exception ArgumentException if <EM>il</EM> is null. **********************************************/ internal void CreateMethodBodyHelper(ILGenerator il) { __ExceptionInfo[] excp; int counter = 0; int[] filterAddrs; int[] catchAddrs; int[] catchEndAddrs; Type[] catchClass; int[] type; int numCatch; int start, end; ModuleBuilder dynMod = (ModuleBuilder)m_module; m_containingType.ThrowIfCreated(); if (m_bIsBaked) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodHasBody")); } if (il == null) { throw new ArgumentNullException("il"); } if (il.m_methodBuilder != this && il.m_methodBuilder != null) { // you don't need to call CreateMethodBody when you get your ILGenerator // through MethodBuilder::GetILGenerator. // throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadILGeneratorUsage")); } if ((m_dwMethodImplFlags & MethodImplAttributes.PreserveSig) != 0 || (m_dwMethodImplFlags & MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL || (m_dwMethodImplFlags & MethodImplAttributes.Unmanaged) != 0 || (m_iAttributes & MethodAttributes.PinvokeImpl) != 0) { // cannot attach method body if methodimpl is marked not marked as managed IL // @todo: what error should we throw here? // throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ShouldNotHaveMethodBody")); } if (il.m_ScopeTree.m_iOpenScopeCount != 0) { // There are still unclosed local scope throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_OpenLocalVariableScope")); } m_ubBody = il.BakeByteArray(); m_RVAFixups = il.GetRVAFixups(); mm_mdMethodFixups = il.GetTokenFixups(); //Okay, now the fun part. Calculate all of the exceptions. excp = il.GetExceptions(); m_numExceptions = CalculateNumberOfExceptions(excp); if (m_numExceptions > 0) { m_exceptions = new __ExceptionInstance[m_numExceptions]; for (int i = 0; i < excp.Length; i++) { filterAddrs = excp[i].GetFilterAddresses(); catchAddrs = excp[i].GetCatchAddresses(); catchEndAddrs = excp[i].GetCatchEndAddresses(); catchClass = excp[i].GetCatchClass(); // track the reference of the catch class for (int j = 0; j < catchClass.Length; j++) { if (catchClass[j] != null) { dynMod.GetTypeToken(catchClass[j]); } } numCatch = excp[i].GetNumberOfCatches(); start = excp[i].GetStartAddress(); end = excp[i].GetEndAddress(); type = excp[i].GetExceptionTypes(); for (int j = 0; j < numCatch; j++) { int tkExceptionClass = 0; if (catchClass[j] != null) { tkExceptionClass = dynMod.GetTypeToken(catchClass[j]).Token; } switch (type[j]) { case __ExceptionInfo.None: case __ExceptionInfo.Fault: case __ExceptionInfo.Filter: m_exceptions[counter++] = new __ExceptionInstance(start, end, filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass); break; case __ExceptionInfo.Finally: m_exceptions[counter++] = new __ExceptionInstance(start, excp[i].GetFinallyEndAddress(), filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass); break; } } } } m_bIsBaked = true; if (dynMod.GetSymWriter() != null) { // set the debugging information such as scope and line number // if it is in a debug module // SymbolToken tk = new SymbolToken(m_mdMethod.Token); ISymbolWriter symWriter = dynMod.GetSymWriter(); // call OpenMethod to make this method the current method symWriter.OpenMethod(tk); // call OpenScope because OpenMethod no longer implicitly creating // the top-levelsmethod scope // symWriter.OpenScope(0); if (m_localSymInfo != null) { m_localSymInfo.EmitLocalSymInfo(symWriter); } il.m_ScopeTree.EmitScopeTree(symWriter); il.m_LineNumberInfo.EmitLineNumberInfo(symWriter); symWriter.CloseScope(il.m_length); symWriter.CloseMethod(); } }
internal void CreateMethodBodyHelper(ILGenerator il) { // Sets the IL of the method. An ILGenerator is passed as an argument and the method // queries this instance to get all of the information which it needs. if (il == null) { throw new ArgumentNullException(nameof(il)); } __ExceptionInfo[] excp; int counter = 0; int[] filterAddrs; int[] catchAddrs; int[] catchEndAddrs; Type[] catchClass; int[] type; int numCatch; int start, end; ModuleBuilder dynMod = (ModuleBuilder)m_module; m_containingType.ThrowIfCreated(); if (m_bIsBaked) { throw new InvalidOperationException(SR.InvalidOperation_MethodHasBody); } if (il.m_methodBuilder != this && il.m_methodBuilder != null) { // you don't need to call DefineBody when you get your ILGenerator // through MethodBuilder::GetILGenerator. // throw new InvalidOperationException(SR.InvalidOperation_BadILGeneratorUsage); } ThrowIfShouldNotHaveBody(); if (il.m_ScopeTree.m_iOpenScopeCount != 0) { // There are still unclosed local scope throw new InvalidOperationException(SR.InvalidOperation_OpenLocalVariableScope); } m_ubBody = il.BakeByteArray(); m_mdMethodFixups = il.GetTokenFixups(); //Okay, now the fun part. Calculate all of the exceptions. excp = il.GetExceptions() !; int numExceptions = CalculateNumberOfExceptions(excp); if (numExceptions > 0) { m_exceptions = new ExceptionHandler[numExceptions]; for (int i = 0; i < excp.Length; i++) { filterAddrs = excp[i].GetFilterAddresses(); catchAddrs = excp[i].GetCatchAddresses(); catchEndAddrs = excp[i].GetCatchEndAddresses(); catchClass = excp[i].GetCatchClass(); numCatch = excp[i].GetNumberOfCatches(); start = excp[i].GetStartAddress(); end = excp[i].GetEndAddress(); type = excp[i].GetExceptionTypes(); for (int j = 0; j < numCatch; j++) { int tkExceptionClass = 0; if (catchClass[j] != null) { tkExceptionClass = dynMod.GetTypeTokenInternal(catchClass[j]).Token; } switch (type[j]) { case __ExceptionInfo.None: case __ExceptionInfo.Fault: case __ExceptionInfo.Filter: m_exceptions[counter++] = new ExceptionHandler(start, end, filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass); break; case __ExceptionInfo.Finally: m_exceptions[counter++] = new ExceptionHandler(start, excp[i].GetFinallyEndAddress(), filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass); break; } } } } m_bIsBaked = true; if (dynMod.GetSymWriter() != null) { // set the debugging information such as scope and line number // if it is in a debug module // SymbolToken tk = new SymbolToken(MetadataTokenInternal); ISymbolWriter symWriter = dynMod.GetSymWriter() !; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/2388 // call OpenMethod to make this method the current method symWriter.OpenMethod(tk); // call OpenScope because OpenMethod no longer implicitly creating // the top-levelsmethod scope // symWriter.OpenScope(0); if (m_symCustomAttrs != null) { foreach (SymCustomAttr symCustomAttr in m_symCustomAttrs) { dynMod.GetSymWriter() !.SetSymAttribute( new SymbolToken(MetadataTokenInternal), symCustomAttr.m_name, symCustomAttr.m_data); } } if (m_localSymInfo != null) { m_localSymInfo.EmitLocalSymInfo(symWriter); } il.m_ScopeTree.EmitScopeTree(symWriter); il.m_LineNumberInfo.EmitLineNumberInfo(symWriter); symWriter.CloseScope(il.ILOffset); symWriter.CloseMethod(); } }
void CreateScopes(MethodBody body, ScopeCollection scopes) { foreach (Scope s in scopes) { int startOffset = s.Start.Offset; int endOffset = s.End == body.Instructions.Outside ? body.Instructions[body.Instructions.Count - 1].Offset + 1 : s.End.Offset; m_writer.OpenScope(startOffset); m_writer.UsingNamespace(body.Method.DeclaringType.Namespace); m_writer.OpenNamespace(body.Method.DeclaringType.Namespace); int start = Math.Max(0, body.Instructions.IndexOf(s.Start)); int end = s.End == body.Instructions.Outside ? body.Instructions.Count - 1 : body.Instructions.IndexOf(s.End); ArrayList instructions = new ArrayList(); for (int i = start; i <= end; i++) { if (body.Instructions[i] != null && body.Instructions[i].SequencePoint != null) { instructions.Add(body.Instructions [i]); } } Document doc = null; int [] offsets = new int [instructions.Count]; int [] startRows = new int [instructions.Count]; int [] startCols = new int [instructions.Count]; int [] endRows = new int [instructions.Count]; int [] endCols = new int [instructions.Count]; for (int i = 0; i < instructions.Count; i++) { Instruction instr = (Instruction)instructions [i]; offsets [i] = instr.Offset; if (doc == null) { doc = instr.SequencePoint.Document; } startRows [i] = instr.SequencePoint.StartLine; startCols [i] = instr.SequencePoint.StartColumn; endRows [i] = instr.SequencePoint.EndLine; endCols [i] = instr.SequencePoint.EndColumn; } if (doc != null) { m_writer.DefineSequencePoints(GetDocument(doc), offsets, startRows, startCols, endRows, endCols); } // Cecil PDB writer does not yet write the variable names. // This is not yet implemented. // TODO local variable support //CreateLocalVariable (s, startOffset, endOffset); //CreateScopes (body, s.Scopes); m_writer.CloseNamespace(); m_writer.CloseScope(endOffset); } }
internal void CreateMethodBodyHelper(ILGenerator il) { if (il == null) { throw new ArgumentNullException("il"); } int num = 0; ModuleBuilder module = this.m_module; this.m_containingType.ThrowIfCreated(); if (this.m_bIsBaked) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodHasBody")); } if ((il.m_methodBuilder != this) && (il.m_methodBuilder != null)) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadILGeneratorUsage")); } this.ThrowIfShouldNotHaveBody(); if (il.m_ScopeTree.m_iOpenScopeCount != 0) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_OpenLocalVariableScope")); } this.m_ubBody = il.BakeByteArray(); this.m_RVAFixups = il.GetRVAFixups(); this.m_mdMethodFixups = il.GetTokenFixups(); __ExceptionInfo[] exceptions = il.GetExceptions(); this.m_numExceptions = this.CalculateNumberOfExceptions(exceptions); if (this.m_numExceptions > 0) { this.m_exceptions = new __ExceptionInstance[this.m_numExceptions]; for (int i = 0; i < exceptions.Length; i++) { int[] filterAddresses = exceptions[i].GetFilterAddresses(); int[] catchAddresses = exceptions[i].GetCatchAddresses(); int[] catchEndAddresses = exceptions[i].GetCatchEndAddresses(); Type[] catchClass = exceptions[i].GetCatchClass(); for (int j = 0; j < catchClass.Length; j++) { if (catchClass[j] != null) { module.GetTypeTokenInternal(catchClass[j]); } } int numberOfCatches = exceptions[i].GetNumberOfCatches(); int startAddress = exceptions[i].GetStartAddress(); int endAddress = exceptions[i].GetEndAddress(); int[] exceptionTypes = exceptions[i].GetExceptionTypes(); for (int k = 0; k < numberOfCatches; k++) { int exceptionClass = 0; if (catchClass[k] != null) { exceptionClass = module.GetTypeTokenInternal(catchClass[k]).Token; } switch (exceptionTypes[k]) { case 0: case 1: case 4: this.m_exceptions[num++] = new __ExceptionInstance(startAddress, endAddress, filterAddresses[k], catchAddresses[k], catchEndAddresses[k], exceptionTypes[k], exceptionClass); break; case 2: this.m_exceptions[num++] = new __ExceptionInstance(startAddress, exceptions[i].GetFinallyEndAddress(), filterAddresses[k], catchAddresses[k], catchEndAddresses[k], exceptionTypes[k], exceptionClass); break; } } } } this.m_bIsBaked = true; if (module.GetSymWriter() != null) { SymbolToken method = new SymbolToken(this.MetadataTokenInternal); ISymbolWriter symWriter = module.GetSymWriter(); symWriter.OpenMethod(method); symWriter.OpenScope(0); if (this.m_symCustomAttrs != null) { foreach (SymCustomAttr attr in this.m_symCustomAttrs) { module.GetSymWriter().SetSymAttribute(new SymbolToken(this.MetadataTokenInternal), attr.m_name, attr.m_data); } } if (this.m_localSymInfo != null) { this.m_localSymInfo.EmitLocalSymInfo(symWriter); } il.m_ScopeTree.EmitScopeTree(symWriter); il.m_LineNumberInfo.EmitLineNumberInfo(symWriter); symWriter.CloseScope(il.ILOffset); symWriter.CloseMethod(); } }