summaryrefslogtreecommitdiff
path: root/src/vm/message.h
blob: 06c04020677f00d337b018d224b3c7adf3a39095 (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
// 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.

/*============================================================
**
** File:    message.h
**
** Purpose: Encapsulates a function call frame into a message 
**          object with an interface that can enumerate the 
**          arguments of the messagef
**
**

===========================================================*/
#ifndef ___MESSAGE_H___
#define ___MESSAGE_H___

#ifndef FEATURE_REMOTING
#error FEATURE_REMOTING is not set, please do not include message.h
#endif

#include "fcall.h"

//+----------------------------------------------------------
//
//  Struct:     MessageObject
// 
//  Synopsis:   Physical mapping of the System.Runtime.Remoting.Message
//              object.
// 
//
//------------------------------------------------------------
class MessageObject : public Object
{
    friend class MscorlibBinder;

public:
    MetaSig* GetResetMetaSig()
    {
        CONTRACT(MetaSig*)
        {
            NOTHROW;
            GC_NOTRIGGER;
            MODE_COOPERATIVE;
            PRECONDITION(CheckPointer(pMetaSigHolder));
            POSTCONDITION(CheckPointer(RETVAL));
            SO_TOLERANT;
        }
        CONTRACT_END;

        pMetaSigHolder->Reset();
        RETURN pMetaSigHolder;
    }            

    FramedMethodFrame *GetFrame()
    {
        CONTRACT(FramedMethodFrame *)
        {
            NOTHROW;
            GC_NOTRIGGER;
            MODE_COOPERATIVE;
            POSTCONDITION(CheckPointer(RETVAL));
        }
        CONTRACT_END;

        RETURN pFrame;
    }

    MethodDesc *GetMethodDesc()
    {
        CONTRACT(MethodDesc *)
        {
            NOTHROW;
            GC_NOTRIGGER;
            MODE_COOPERATIVE;
            POSTCONDITION(CheckPointer(RETVAL));
            SO_TOLERANT;
        }
        CONTRACT_END;

        RETURN pMethodDesc;
    }

    MethodDesc *GetDelegateMD()
    {
        CONTRACT(MethodDesc *)
        {
            NOTHROW;
            GC_NOTRIGGER;
            MODE_COOPERATIVE;
            POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
            SO_TOLERANT;
        }
        CONTRACT_END;

        RETURN pDelegateMD;
    }
    
    INT32 GetFlags()
    {
        CONTRACTL
        {
            NOTHROW;
            GC_NOTRIGGER;
            MODE_COOPERATIVE;
            SO_TOLERANT;
        }
        CONTRACTL_END;

        return iFlags;
    }

private:
    STRINGREF          pMethodName;    // Method name
    BASEARRAYREF       pMethodSig;     // Array of parameter types
    OBJECTREF          pMethodBase;    // Reflection method object
    OBJECTREF          pHashTable;     // hashtable for properties
    STRINGREF          pURI;           // object's URI
    STRINGREF          pTypeName;       // not used in VM, placeholder
    OBJECTREF          pFault;         // exception

    OBJECTREF          pID;            // not used in VM, placeholder
    OBJECTREF          pSrvID;         // not used in VM, placeholder
    OBJECTREF          pArgMapper;     // not used in VM, placeholder
    OBJECTREF          pCallCtx;       // not used in VM, placeholder

    FramedMethodFrame  *pFrame;
    MethodDesc         *pMethodDesc;
    MetaSig            *pMetaSigHolder;
    MethodDesc         *pDelegateMD;
    TypeHandle          thGoverningType;
    INT32               iFlags;
    CLR_BOOL            initDone;       // called the native Init routine
};

#ifdef USE_CHECKED_OBJECTREFS
typedef REF<MessageObject> MESSAGEREF;
#else
typedef MessageObject* MESSAGEREF;
#endif

// *******
// Note: Needs to be in sync with flags in Message.cs
// *******
enum
{
    MSGFLG_BEGININVOKE = 0x01,
    MSGFLG_ENDINVOKE   = 0x02,
    MSGFLG_CTOR        = 0x04,
    MSGFLG_ONEWAY      = 0x08,
    MSGFLG_FIXEDARGS   = 0x10,
    MSGFLG_VARARGS     = 0x20
};

//+----------------------------------------------------------
//
//  Class:      CMessage
// 
//  Synopsis:   EE counterpart to Microsoft.Runtime.Message.
//              Encapsulates code to read a function call 
//              frame into an interface that can enumerate
//              the parameters.
// 
//
//------------------------------------------------------------
class CMessage
{
public:
    // public fcalls.
    static FCDECL1(INT32, GetArgCount, MessageObject *pMsg);
    static FCDECL2(Object*, GetArg, MessageObject* pMessage, INT32 argNum);
    static FCDECL1(Object*, GetArgs, MessageObject* pMessageUNSAFE);
    static FCDECL3(void, PropagateOutParameters, MessageObject* pMessageUNSAFE, ArrayBase* pOutPrmsUNSAFE, Object* RetValUNSAFE);
    static FCDECL1(Object*, GetReturnValue, MessageObject* pMessageUNSAFE);
    static FCDECL3(void, GetAsyncBeginInfo, MessageObject* pMessageUNSAFE, OBJECTREF* ppACBD, OBJECTREF* ppState);
    static FCDECL1(LPVOID, GetAsyncResult, MessageObject* pMessageUNSAFE);
    static FCDECL1(Object*, GetAsyncObject, MessageObject* pMessageUNSAFE);
    static FCDECL1(void, DebugOut, StringObject* pOutUNSAFE);
    static FCDECL2(FC_BOOL_RET, Dispatch, MessageObject* pMessageUNSAFE, Object* pServerUNSAFE);
    static FCDECL1(FC_BOOL_RET, HasVarArgs, MessageObject * poMessage);

public:
    // public helper
    static void GetObjectFromStack(OBJECTREF* ppDest, PVOID val, const CorElementType eType, TypeHandle ty, BOOL fIsByRef = FALSE, FramedMethodFrame *pFrame = NULL);

private:
    // private helpers
    static PVOID GetStackPtr(INT32 ndx, FramedMethodFrame *pFrame, MetaSig *pSig);       
    static int GetStackOffset (FramedMethodFrame *pFrame, ArgIterator *pArgIter, MetaSig *pSig);
    static INT64 __stdcall CallMethod(const void *pTarget,
                                        INT32 cArgs,
                                        FramedMethodFrame *pFrame,
                                        OBJECTREF pObj);
    static INT64 CopyOBJECTREFToStack(PVOID pvDest, OBJECTREF *pSrc, CorElementType typ, TypeHandle ty, MetaSig *pSig, BOOL fCopyClassContents);
    static LPVOID GetLastArgument(MESSAGEREF *pMsg);
    static void AppendAssemblyName(CQuickBytes &out, const CHAR* str);
};

#endif // ___MESSAGE_H___