EmitLocalSymInfo() private method

private EmitLocalSymInfo ( ISymbolWriter symWriter ) : void
symWriter ISymbolWriter
return void
Esempio n. 1
0
        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();

                // 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();
            }
        }