summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs
blob: 9a43be90adb3aef4e0daeb05fbb8bc4489a63f08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Reflection;
using System.Security.Permissions;
using System.Runtime.InteropServices;

namespace System.Reflection.Emit 
{
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(_LocalBuilder))]
    [System.Runtime.InteropServices.ComVisible(true)]
    public sealed class LocalBuilder : LocalVariableInfo, _LocalBuilder
    { 
        #region Private Data Members
        private int m_localIndex;
        private Type m_localType;
        private MethodInfo m_methodBuilder;
        private bool m_isPinned;
        #endregion

        #region Constructor
        private LocalBuilder() { }
        internal LocalBuilder(int localIndex, Type localType, MethodInfo methodBuilder) 
            : this(localIndex, localType, methodBuilder, false) { }
        internal LocalBuilder(int localIndex, Type localType, MethodInfo methodBuilder, bool isPinned) 
        {
            m_isPinned = isPinned;
            m_localIndex = localIndex;
            m_localType = localType;
            m_methodBuilder = methodBuilder;
        }
        #endregion

        #region Internal Members
        internal int GetLocalIndex() 
        {
            return m_localIndex;
        }
        internal MethodInfo GetMethodBuilder() 
        {
            return m_methodBuilder;
        }
        #endregion

        #region LocalVariableInfo Override
        public override bool IsPinned { get { return m_isPinned; } }
        public override Type LocalType 
        {
            get 
            { 
                return m_localType; 
            }
        }        
        public override int LocalIndex { get { return m_localIndex; } }
        #endregion

        #region Public Members
        public void SetLocalSymInfo(String name)
        {
            SetLocalSymInfo(name, 0, 0);
        }            

        public void SetLocalSymInfo(String name, int startOffset, int endOffset)
        {
            ModuleBuilder dynMod;
            SignatureHelper sigHelp;
            int sigLength;
            byte[] signature;
            byte[] mungedSig;
            int index;

            MethodBuilder methodBuilder = m_methodBuilder as MethodBuilder;
            if (methodBuilder == null) 
                // it's a light code gen entity
                throw new NotSupportedException();
            dynMod = (ModuleBuilder) methodBuilder.Module;
            if (methodBuilder.IsTypeCreated())
            {
                // cannot change method after its containing type has been created
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeHasBeenCreated"));
            }
    
            // set the name and range of offset for the local
            if (dynMod.GetSymWriter() == null)
            {
                // cannot set local name if not debug module
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
            }
    
            sigHelp = SignatureHelper.GetFieldSigHelper(dynMod);
            sigHelp.AddArgument(m_localType);
            signature = sigHelp.InternalGetSignature(out sigLength);
    
            // The symbol store doesn't want the calling convention on the
            // front of the signature, but InternalGetSignature returns
            // the callinging convention. So we strip it off. This is a
            // bit unfortunate, since it means that we need to allocate
            // yet another array of bytes...  
            mungedSig = new byte[sigLength - 1];
            Array.Copy(signature, 1, mungedSig, 0, sigLength - 1);
            
            index = methodBuilder.GetILGenerator().m_ScopeTree.GetCurrentActiveScopeIndex();
            if (index == -1)
            {
                // top level scope information is kept with methodBuilder
                methodBuilder.m_localSymInfo.AddLocalSymInfo(
                     name,
                     mungedSig,
                     m_localIndex,   
                     startOffset,
                     endOffset);
            }
            else
            {
                methodBuilder.GetILGenerator().m_ScopeTree.AddLocalSymInfoToCurrentScope(
                     name,
                     mungedSig,
                     m_localIndex,   
                     startOffset,
                     endOffset);
            }
        }
        #endregion

#if !FEATURE_CORECLR
        void _LocalBuilder.GetTypeInfoCount(out uint pcTInfo)
        {
            throw new NotImplementedException();
        }

        void _LocalBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
        {
            throw new NotImplementedException();
        }

        void _LocalBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
        {
            throw new NotImplementedException();
        }

        void _LocalBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
        {
            throw new NotImplementedException();
        }
#endif
    }
}