summaryrefslogtreecommitdiff
path: root/src/vm/reflectclasswriter.cpp
blob: 093d5f7d9cd2d7ca0776d9b8d557316c4cb1b189 (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
// 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.
//

//

#include "common.h" 
#include "reflectclasswriter.h"

// Forward declaration.
STDAPI  GetMetaDataInternalInterfaceFromPublic(
    IUnknown    *pv,                    // [IN] Given interface.
    REFIID      riid,                   // [IN] desired interface
    void        **ppv);                 // [OUT] returned interface

//******************************************************
//*
//* constructor for RefClassWriter
//*
//******************************************************
HRESULT RefClassWriter::Init(ICeeGen *pCeeGen, IUnknown *pUnk, LPCWSTR szName)
{
    CONTRACT(HRESULT) {
        NOTHROW;
        GC_NOTRIGGER;
        // we know that the com implementation is ours so we use mode-any to simplify
        // having to switch mode 
        MODE_ANY; 
        INJECT_FAULT(CONTRACT_RETURN(E_OUTOFMEMORY));
        
        PRECONDITION(CheckPointer(pCeeGen));
        PRECONDITION(CheckPointer(pUnk));

        POSTCONDITION(SUCCEEDED(RETVAL) ? CheckPointer(m_emitter) : TRUE);
        POSTCONDITION(SUCCEEDED(RETVAL) ? CheckPointer(m_importer) : TRUE);
        POSTCONDITION(SUCCEEDED(RETVAL) ? CheckPointer(m_pEmitHelper) : TRUE);
        POSTCONDITION(SUCCEEDED(RETVAL) ? CheckPointer(m_internalimport) : TRUE);
    }
    CONTRACT_END;

    // Initialize the Import and Emitter interfaces
    m_emitter = NULL;
    m_importer = NULL;
    m_internalimport = NULL;
    m_pCeeFileGen = NULL;
    m_ceeFile = NULL;
    m_ulResourceSize = 0;
    m_tkFile = mdFileNil;

    m_pCeeGen = pCeeGen;
    pCeeGen->AddRef();

    // Get the interfaces
    HRESULT hr = pUnk->QueryInterface(IID_IMetaDataEmit2, (void**)&m_emitter);
    if (FAILED(hr))
        RETURN(hr);

    hr = pUnk->QueryInterface(IID_IMetaDataImport, (void**)&m_importer);
    if (FAILED(hr))
        RETURN(hr);

    hr = pUnk->QueryInterface(IID_IMetaDataEmitHelper, (void**)&m_pEmitHelper);
    if (FAILED(hr))
        RETURN(hr);

    hr = GetMetaDataInternalInterfaceFromPublic(pUnk, IID_IMDInternalImport, (void**)&m_internalimport);
    if (FAILED(hr))
        RETURN(hr);

    // <TODO> We will need to set this at some point.</TODO>
    hr = m_emitter->SetModuleProps(szName);
    if (FAILED(hr))
        RETURN(hr);

    RETURN(S_OK);
}


//******************************************************
//*
//* destructor for RefClassWriter
//*
//******************************************************
RefClassWriter::~RefClassWriter()
{
    CONTRACTL {
        NOTHROW;
        GC_TRIGGERS;
        // we know that the com implementation is ours so we use mode-any to simplify
        // having to switch mode 
        MODE_ANY; 
        FORBID_FAULT;
    }
    CONTRACTL_END;

    if (m_emitter) {
        m_emitter->Release();
    }

    if (m_importer) {
        m_importer->Release();
    }

    if (m_pEmitHelper) {
        m_pEmitHelper->Release();
    }

    if (m_internalimport) {
        m_internalimport->Release();
    }

    if (m_pCeeGen) {
        m_pCeeGen->Release();
        m_pCeeGen = NULL;
    }

    if (m_pOnDiskEmitter) {
        m_pOnDiskEmitter->Release();
        m_pOnDiskEmitter = NULL;
    }
}