summaryrefslogtreecommitdiff
path: root/src/vm/compactlayoutwriter.h
blob: 56ba1a69ae4c90533ea2685c5149bd43f08444f2 (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
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. 
//

//

//

#include "corhdr.h"

#if !defined(_CompactLayoutWriter) && defined(MDIL)
#define _CompactLayoutWriter
#include "mdil.h"

class ZapImage;

struct InlineContext;

class ICompactLayoutWriter
{
public:
    // Prepare to write CTL for a type.
    virtual
    void Reset() = 0;

    virtual
    void GenericType(DWORD typeArgCount) = 0;

    enum ComFlags // additional flags on types besides CorTypeAttr
    {
        CF_COMOBJECTTYPE                    = 0x80000000,
        CF_COMCLASSINTERFACE                = 0x40000000,
        CF_COMEVENTINTERFACE                = 0x20000000,

        // com interface types
        CF_IFACEATTRMASK                    = 0x18000000,
        CF_DUAL                             = 0x00000000,
        CF_VTABLE                           = 0x08000000,
        CF_DISPATCH                         = 0x10000000,
        CF_INSPECTABLE                      = 0x18000000,

        // interfaces don't have finalizers so we can 
        // reuse the bits interfaces use to specify dispatch type
        CF_FINALIZER                        = 0x08000000,
        CF_CRITICALFINALIZER                = 0x10000000,

        // fixed value type statics
        CF_FIXED_ADDRESS_VT_STATICS         = 0x04000000,

        // type equivalence on struct parameters
        CF_DEPENDS_ON_COM_IMPORT_STRUCTS    = 0x02000000,

        // is type equivalent?
        CF_TYPE_EQUIVALENT                  = 0x01000000,

        CF_CONTAINS_STACK_PTR               = 0x00800000,

        // this type has the UnsafeValueType CA attached to it
        CF_UNSAFEVALUETYPE                  = 0x00400000,
    };

    enum SecurityFlags
    {
        SF_UNKNOWN                          = 0,
        SF_TRANSPARENT                      = 1,
        SF_ALL_TRANSPARENT                  = 2,
        SF_CRTIICAL                         = 3,
        SF_CRITICAL_TAS                     = 4,
        SF_ALLCRITICAL                      = 5,
        SF_ALLCRITICAL_TAS                  = 6,
        SF_TAS_NOTCRITICAL                  = 7,
    };

    virtual
    void StartType( DWORD  flags,							// CorTypeAttr plus perhaps other flags
                    DWORD  typeDefToken,					// typedef token for this type
                    DWORD  baseTypeToken,					// type this type is derived from, if any
                    DWORD  enclosingTypeToken,				// type this type is nested in, if any
                    DWORD  interfaceCount,					// how many times ImplementInterface() will be called
                    DWORD  fieldCount,						// how many times Field() will be called
                    DWORD  methodCount,						// how many times Method() will be called
                    DWORD  newVirtualMethodCount,			// how many new virtuals this type defines
                    DWORD  overrideVirtualMethodCount ) = 0;// how many virtuals this type overrides

    // Call once for each interface implemented by the
    // class directly (not those implemented in base classes)
    virtual
    void ImplementInterface( DWORD interfaceTypeToken ) = 0;


    virtual
    void ExtendedTypeFlags( DWORD flags ) = 0;

    virtual
    void SpecialType( SPECIAL_TYPE type) = 0;

    virtual 
    enum FieldStorage
    {
        FS_INSTANCE,
        FS_STATIC,
        FS_THREADLOCAL,
        FS_CONTEXTLOCAL,
        FS_RVA
    };

    enum FieldProtection // parallels CorFieldAttr
    {
        FP_PRIVATE_SCOPE     = 0x0,     // Member not referenceable.
        FP_PRIVATE           = 0x1,     // Accessible only by the parent type.
        FP_FAM_AND_ASSEM     = 0x2,     // Accessible by sub-types only in this Assembly.
        FP_ASSEMBLY          = 0x3,     // Accessibly by anyone in the Assembly.
        FP_FAMILY            = 0x4,     // Accessible only by type and sub-types.
        FP_FAM_OR_ASSEM      = 0x5,     // Accessibly by sub-types anywhere, plus anyone in assembly.
        FP_PUBLIC            = 0x6,     // Accessibly by anyone who has visibility to this scope.
    };

    // Call once for each field the class declares directly
    // valueTypeToken is non-0 iff fieldType == ELEMENT_TYPE_VALUETYPE
    // not all CorElementTypes are allowed
    virtual
    void Field( DWORD           fieldToken,		// an mdFieldDef
                FieldStorage    fieldStorage,
                FieldProtection fieldProtection,
                CorElementType  fieldType,
                DWORD			fieldOffset,
                DWORD           valueTypeToken) = 0;

    // call once for each method implementing a contract
    // in an interface.
    // declToken is the token of the method that is implemented
    // implToken is the method body that implements it
    virtual
    void ImplementInterfaceMethod(DWORD declToken,
                                  DWORD implToken) = 0;

    enum ImplHints
    {
        IH_CTOR                         = 0x0010,
        IH_DEFAULT_CTOR                 = 0x0020,   // this one will have IH_CTOR set also
        IH_CCTOR                        = 0x0040,

        IH_DELEGATE_INVOKE              = 0x0080,   // this the Invoke method of a delegate
        IH_DELEGATE_BEGIN_INVOKE        = 0x0090,   // this the BeginInvoke method of a delegate
        IH_DELEGATE_END_INVOKE          = 0x00A0,   // this the EndInvoke method of a delegate

        IH_TRANSPARENCY_MASK            = 0x0C00,
        IH_TRANSPARENCY_NO_INFO         = 0x0000,
        IH_TRANSPARENCY_TRANSPARENT     = 0x0400,
        IH_TRANSPARENCY_CRITICAL        = 0x0800,
        IH_TRANSPARENCY_TREAT_AS_SAFE   = 0x0C00,

        IH_BY_ORDINAL                   = 0x1000,   // this applies only to DllImport and DllExport methods 
        IH_IS_VERIFIED                  = 0x2000,   // IH_IS_VERIFIED and IH_IS_VERIFIABLE match
        IH_IS_VERIFIABLE                = 0x4000,   // IsVerified and IsVerifiable on the MethodDesc

        IH_HASMETHODIMPL                = 0x8000,   // Method overrides a (non-interface) method via MethodImpl,
                                                    // which will be reported via MethodImpl lateron
    };

    enum StubMethodFlags
    {
        SF_PINVOKE                   = 0,
        SF_DELEGATE_PINVOKE          = 1,
        SF_CALLI_PINVOKE             = 2,
        SF_REVERSE_PINVOKE           = 3,
        SF_CLR_TO_COM                = 4,
        SF_COM_TO_CLR                = 5,
        SF_STUB_KIND_MASK            = 0x0000000f,

        SF_HAS_COPY_CONSTRUCTED_ARGS = 0x00000010,
        SF_NEEDS_STUB_SIGNATURE      = 0x00000020,

        SF_STACK_ARG_SIZE_MASK       = 0xFFFC0000,
    };

    enum CorElementTypeMDIL
    {
        ELEMENT_TYPE_NATIVE_VALUETYPE = 0x08 | ELEMENT_TYPE_MODIFIER
    };

    // call once for each method except PInvoke methods
    virtual
    void Method(DWORD methodAttrs,
                DWORD implFlags,
                DWORD implHints, // have to figure how exactly we do this so it's not so tied to the CLR implementation
                DWORD methodToken,
                DWORD overriddenMethodToken) = 0;

    // call once for each PInvoke method
    virtual
    void PInvokeMethod( DWORD methodAttrs,
                        DWORD implFlags,
                        DWORD implHints, // have to figure how exactly we do this so it's not so tied to the CLR implementation
                        DWORD methodToken,
                        LPCSTR moduleName,
                        LPCSTR entryPointName,
                        WORD wLinkFlags) = 0;
    
    // call once for each DllExport method (Redhawk only feature, at least for now)
    virtual
    void DllExportMethod( DWORD methodAttrs,
                          DWORD implFlags,
                          DWORD implHints, // have to figure how exactly we do this so it's not so tied to the CLR implementation
                          DWORD methodToken,
                          LPCSTR entryPointName,
                          DWORD callingConvention) = 0;
    
    virtual
    void StubMethod( DWORD dwMethodFlags,
                     DWORD sigToken,
                     DWORD methodToken) = 0;

    virtual
    void StubAssociation( DWORD ownerToken,
                          DWORD *stubTokens,
                          size_t numStubs) = 0;

    // call once for each method impl
    virtual
    void MethodImpl(DWORD declToken,
                    DWORD implToken ) = 0;

    // set an explicit size for explicit layout structs
    virtual
    void SizeType(DWORD size) = 0;

    // specify the packing size
    virtual
    void PackType(DWORD packingSize) = 0;

    // specify a generic parameter to a type or method
    virtual
    void GenericParameter(DWORD genericParamToken, DWORD flags) = 0;

    enum NativeFlags
    {
        NF_BESTFITMAP             = 0x01,
        NF_THROWONUNMAPPABLECHAR  = 0x02,

        // sometimes we store a VARTYPE in the upper bits - this is how much to shift
        NF_VARTYPE_SHIFT          = 8,
    };

    // specify a field representation on the native side
    virtual
    void NativeField(DWORD            fieldToken,		// an mdFieldDef
                     DWORD            nativeType,       // really an NStructFieldType
                     DWORD			  nativeOffset,
                     DWORD            count,
                     DWORD            flags,
                     DWORD            typeToken1,
                     DWORD            typeToken2) = 0;

    // specify guid info for interface types
    virtual
    void GuidInformation(GuidInfo *guidInfo) = 0;

    // end the description of the type
    virtual
    void EndType() = 0;

    // return a token for a method desc
    // this is trivial in the case of a non-generic method in our own module, not so trivial
    // otherwise - we may have to generate new moduleref, typeref, typespec, methodspec tokens
    virtual
    mdMemberRef GetTokenForMethodDesc(MethodDesc *methodDesc, MethodTable *pMT = NULL) = 0;

    virtual
    mdTypeSpec GetTypeSpecToken(PCCOR_SIGNATURE pSig, DWORD cbSig) = 0;

    virtual
    mdToken GetTokenForType(MethodTable *pMT) = 0;

    virtual
    mdToken GetTokenForType(CORINFO_CLASS_HANDLE type) = 0;

    virtual 
    mdToken GetTokenForType(InlineContext *inlineContext, CORINFO_ARG_LIST_HANDLE argList) = 0;

    virtual
    mdToken GetTokenForMethod(CORINFO_METHOD_HANDLE method) = 0;

    virtual
    mdToken GetTokenForField(CORINFO_FIELD_HANDLE field) = 0;

    virtual
    mdToken GetTokenForSignature(PCCOR_SIGNATURE sig) = 0;

    virtual 
    mdToken GetTypeTokenForFieldOrMethod(mdToken fieldOrMethodToken) = 0;

    virtual
    mdToken GetEnclosingClassToken(InlineContext *inlineContext, CORINFO_METHOD_HANDLE methHnd) = 0;

    virtual
    InlineContext *ComputeInlineContext(InlineContext *outerContext, unsigned inlinedMethodToken, unsigned constraintTypeToken, CORINFO_METHOD_HANDLE methHnd) = 0;

    virtual
    DWORD GetFieldOrdinal(CORINFO_MODULE_HANDLE tokenScope, unsigned fieldToken) = 0;

    virtual
    unsigned TranslateToken(InlineContext *inlineContext, unsigned token) = 0;

    virtual
    CorInfoType GetFieldElementType(unsigned fieldToken, CORINFO_MODULE_HANDLE scope, CORINFO_METHOD_HANDLE methHnd, ICorJitInfo *info) = 0;

    virtual
    mdToken GetParentOfMemberRef(CORINFO_MODULE_HANDLE scope, mdMemberRef memberRefToken) = 0;

    virtual
    mdToken GetArrayElementToken(CORINFO_MODULE_HANDLE scope, mdTypeSpec arrayTypeToken) = 0;

    virtual
    mdToken GetCurrentMethodToken(InlineContext *inlineContext, CORINFO_METHOD_HANDLE methHnd) = 0;

    virtual
    bool IsDynamicScope(CORINFO_MODULE_HANDLE scope) = 0;

    virtual
    mdToken GetNextStubToken() = 0;

    virtual
    void Flush() = 0;

    virtual
    void FlushStubData() = 0;

    static ICompactLayoutWriter *MakeCompactLayoutWriter(Module *pModule, ZapImage *pZapImage);
};

#endif