summaryrefslogtreecommitdiff
path: root/src/vm/baseassemblyspec.h
blob: 0a21d95ee878483aff62b2cf6031114b735418e3 (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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ============================================================
//
// BaseAssemblySpec.h
//


//
// Declares the BaseAssemblySpec class
//
// ============================================================

#ifndef __BASE_ASSEMBLY_SPEC_H__
#define __BASE_ASSEMBLY_SPEC_H__

class StackingAllocator;

// a class representing assembly name in Loader
class BaseAssemblySpec
{
protected:
    AssemblyMetaDataInternal    m_context;
    LPCSTR                      m_pAssemblyName; 
    PBYTE                       m_pbPublicKeyOrToken;
    DWORD                       m_cbPublicKeyOrToken;
    DWORD                       m_dwFlags;             // CorAssemblyFlags
    LPCWSTR                     m_wszCodeBase;         // URL to the code
#ifdef FEATURE_FUSION
    LOADCTX_TYPE                m_fParentLoadContext;  // m_pParentAssembly->GetFusionLoadContext()
    ReleaseHolder<IAssemblyName> m_pNameAfterPolicy;
#endif
    LPCSTR                      m_szWinRtTypeNamespace;
    LPCSTR                      m_szWinRtTypeClassName;
    ICLRPrivBinder             *m_pHostBinder;
    int                         m_ownedFlags;
    BOOL                        m_fIntrospectionOnly;
#if defined(FEATURE_CORECLR)
    ICLRPrivBinder             *m_pBindingContext;
#endif // defined(FEATURE_CORECLR)

public:
    enum 
    {
        NAME_OWNED                  = 0x01,
        PUBLIC_KEY_OR_TOKEN_OWNED   = 0x02,
        CODE_BASE_OWNED             = 0x04,
        LOCALE_OWNED                = 0x08,
        CODEBASE_OWNED              = 0x10,
        WINRT_TYPE_NAME_OWNED       = 0x20,
        // Set if ParseName() returned illegal textual identity.
        // Cannot process the string any further.
        BAD_NAME_OWNED              = 0x40,
        ALL_OWNED                   = 0xFF,
    };

    BaseAssemblySpec();
    ~BaseAssemblySpec();

    HRESULT Init(LPCSTR pAssemblyName,
                 const AssemblyMetaDataInternal* pContext, 
                 const BYTE * pbPublicKeyOrToken, DWORD cbPublicKeyOrToken,
                 DWORD dwFlags);

    HRESULT Init(mdToken tkAssemblyRef, IMDInternalImport *pImport);
    HRESULT Init(mdAssembly tkAssemblyRef, IMetaDataAssemblyImport* pImport);
    HRESULT Init(LPCSTR pAssemblyDisplayName);

    HRESULT Init(IAssemblyName *pName);

    // Note that this method does not clone the fields!
    VOID CopyFrom(const BaseAssemblySpec *pSpec);

    VOID    CloneFields(int flags=ALL_OWNED);
    VOID    CloneFieldsToLoaderHeap(int flags, LoaderHeap *pHeap, AllocMemTracker *pamTracker);
    VOID    CloneFieldsToStackingAllocator(StackingAllocator* alloc);

#if defined(FEATURE_CORECLR)
    inline void SetBindingContext(ICLRPrivBinder *pBindingContext)
    {
        LIMITED_METHOD_CONTRACT;
        
        m_pBindingContext = pBindingContext;
    }
    
    inline ICLRPrivBinder* GetBindingContext()
    {
        LIMITED_METHOD_CONTRACT;
        
        return m_pBindingContext;
    }
    
    BOOL IsAssemblySpecForMscorlib();
#endif // defined(FEATURE_CORECLR)
    
    HRESULT ParseName();
    DWORD Hash();

    LPCSTR GetName() const;
    inline void GetName(SString & ssName) const { WRAPPER_NO_CONTRACT; ssName.SetUTF8(GetName()); }
    
    void SetName(LPCSTR szName);
    void SetName(SString const & ssName);

    LPCWSTR GetCodeBase();
    void SetCodeBase(LPCWSTR szCodeBase);

    VOID SetCulture(LPCSTR szCulture);

    VOID ConvertPublicKeyToToken();

    void  SetContext(ASSEMBLYMETADATA* assemblyData);

    inline AssemblyMetaDataInternal *GetContext() { LIMITED_METHOD_CONTRACT; return &m_context; }
    inline AssemblyMetaDataInternal const *GetContext() const { LIMITED_METHOD_CONTRACT; return &m_context; }
    
    BOOL IsStrongNamed() const;
    BOOL HasPublicKey() const;
    BOOL HasPublicKeyToken() const;
    BOOL IsMscorlibSatellite();
    BOOL IsMscorlibDebugSatellite();
    BOOL IsMscorlib();

    //
    // Windows Runtime functions that could not be refactored out to AssemblySpec
    //
    inline LPCSTR GetWinRtTypeNamespace() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_szWinRtTypeNamespace;
    }
    inline LPCSTR GetWinRtTypeClassName() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_szWinRtTypeClassName;
    }

    //****************************************************************************************
    //
    // Creates an IAssemblyName object representing this AssemblySpec.
    //
    //    fMustBeBindable - if set to TRUE, the resulting IAssemblyName may contain internal
    //                      encodings needed to make an identity bindable (this is the case
    //                      for WinRT assemblies: a representative type name is encoded as
    //                      part of the assembly simple name). Be careful to ensure that
    //                      encoded identities are not exposed to customers.
    HRESULT CreateFusionName(
        IAssemblyName **ppName,
        BOOL fIncludeCodeBase = TRUE, /* Used by fusion only */
        BOOL fMustBeBindable = FALSE) const;

#ifdef FEATURE_FUSION
    // for fusion binding
    virtual IAssembly* GetParentIAssembly() =0;

    // for identity comparison
    virtual LPCVOID GetParentAssemblyPtr() =0;

    inline LOADCTX_TYPE GetParentLoadContext()
    {
        LIMITED_METHOD_CONTRACT;
        return m_fParentLoadContext;
    }
#endif

    BOOL IsIntrospectionOnly()
    {
        LIMITED_METHOD_CONTRACT;

        // Important to ensure we return a normalized boolean (the introspection fields
        // of different AssemblySpecs can be compared.)
        return !!m_fIntrospectionOnly;
    }

    VOID SetIntrospectionOnly(BOOL fIntrospectionOnly)
    {
        LIMITED_METHOD_CONTRACT;
        m_fIntrospectionOnly = !!fIntrospectionOnly;
    }

    inline BOOL IsContentType_WindowsRuntime() const
    {
        LIMITED_METHOD_CONTRACT;
#ifdef FEATURE_COMINTEROP
        return IsAfContentType_WindowsRuntime(m_dwFlags);
#else
        return FALSE;
#endif
    }

    void GetEncodedName(SString & ssEncodedName) const;
    
    // Returns true if this object uniquely identifies a single assembly;
    // false otherwise. This will return false for Windows Runtime assemblies,
    // as WinRT assembly names do not represent an identity. This method
    // does not take into account additional attributes such as type namespace
    // and name.
    inline BOOL HasUniqueIdentity() const
    {
        STATIC_CONTRACT_LIMITED_METHOD;
        return !IsContentType_WindowsRuntime();
    }
    
    enum CompareExFlags
    {
        ASC_Default                 = 0x00, // Default comparison policy.
        ASC_DefinitionEquality      = 0x01, // Will not treat non-bindable content types as equivalent.
    };

    BOOL CompareEx(BaseAssemblySpec *pSpec, DWORD dwCompareFlags = ASC_Default);
    static int CompareStrings(LPCUTF8 string1, LPCUTF8 string2);
    static BOOL RefMatchesDef(const BaseAssemblySpec* pRef, const BaseAssemblySpec* pDef);
    static BOOL VerifyBindingString(LPCWSTR pwStr); 

    void GetFileOrDisplayName(DWORD flags, SString &result) const;

    inline void GetPublicKey(
        PBYTE * ppbPublicKey,
        DWORD * pcbPublicKey) const
    {
        LIMITED_METHOD_CONTRACT;
        PRECONDITION(HasPublicKey());
        if (ppbPublicKey != nullptr)
        {
            *ppbPublicKey = m_pbPublicKeyOrToken;
        }
        if (pcbPublicKey != nullptr)
        {
            *pcbPublicKey = m_cbPublicKeyOrToken;
        }
    }

    inline void GetPublicKeyToken(
        PBYTE * ppbPublicKeyToken,
        DWORD * pcbPublicKeyToken) const
    {
        LIMITED_METHOD_CONTRACT;
        PRECONDITION(HasPublicKeyToken());
        if (ppbPublicKeyToken != nullptr)
        {
            *ppbPublicKeyToken = m_pbPublicKeyOrToken;
        }
        if (pcbPublicKeyToken != nullptr)
        {
            *pcbPublicKeyToken = m_cbPublicKeyOrToken;
        }
    }

    inline BOOL IsRetargetable() const
    {
        LIMITED_METHOD_CONTRACT;
        return IsAfRetargetable(m_dwFlags);
    }

#ifdef FEATURE_FUSION
    inline IAssemblyName* GetNameAfterPolicy() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_pNameAfterPolicy;
    }

    inline void ReleaseNameAfterPolicy()
    {
        LIMITED_METHOD_CONTRACT;
        m_pNameAfterPolicy=NULL;
    }

    inline void SetNameAfterPolicy(IAssemblyName* pName)
    {
        LIMITED_METHOD_CONTRACT;
        m_pNameAfterPolicy=pName;
    }


    void SetPEKIND(PEKIND peKind)
    {
        LIMITED_METHOD_CONTRACT;
        C_ASSERT(afPA_None == PAFlag(peNone));
        C_ASSERT(afPA_MSIL == PAFlag(peMSIL));
        C_ASSERT(afPA_x86 == PAFlag(peI386));
        C_ASSERT(afPA_IA64 == PAFlag(peIA64));
        C_ASSERT(afPA_AMD64 == PAFlag(peAMD64));
        C_ASSERT(afPA_ARM == PAFlag(peARM));
        
        _ASSERTE((peKind <= peARM) || (peKind == peInvalid));
        
        m_dwFlags &= ~afPA_FullMask;
        m_dwFlags |= PAFlag(peKind);
    }

    PEKIND GetPEKIND() const
    {
        LIMITED_METHOD_CONTRACT;
        return static_cast<PEKIND>(PAIndex(m_dwFlags));
    }
#endif //FEATURE_FUSION

protected:
    static BOOL CompareRefToDef(const BaseAssemblySpec *pRef, const BaseAssemblySpec *pDef);
};

#endif // __BASE_ASSEMBLY_SPEC_H__