1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | // |
5 | // File: CustomMarshalerInfo.cpp |
6 | // |
7 | |
8 | // |
9 | // Custom marshaler information used when marshaling |
10 | // a parameter with a custom marshaler. |
11 | // |
12 | |
13 | |
14 | #include "common.h" |
15 | |
16 | |
17 | #include "custommarshalerinfo.h" |
18 | #include "mlinfo.h" |
19 | #include "mdaassistants.h" |
20 | #include "sigbuilder.h" |
21 | |
22 | //========================================================================== |
23 | // Implementation of the custom marshaler info class. |
24 | //========================================================================== |
25 | |
26 | CustomMarshalerInfo::CustomMarshalerInfo(BaseDomain *pDomain, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes) |
27 | : m_NativeSize(0) |
28 | , m_hndManagedType(hndManagedType) |
29 | , m_hndCustomMarshaler(NULL) |
30 | , m_pMarshalNativeToManagedMD(NULL) |
31 | , m_pMarshalManagedToNativeMD(NULL) |
32 | , m_pCleanUpNativeDataMD(NULL) |
33 | , m_pCleanUpManagedDataMD(NULL) |
34 | , m_bDataIsByValue(FALSE) |
35 | { |
36 | CONTRACTL |
37 | { |
38 | THROWS; |
39 | GC_TRIGGERS; |
40 | MODE_COOPERATIVE; |
41 | PRECONDITION(CheckPointer(pDomain)); |
42 | } |
43 | CONTRACTL_END; |
44 | |
45 | |
46 | // Make sure the custom marshaller implements ICustomMarshaler. |
47 | if (!hndCustomMarshalerType.GetMethodTable()->CanCastToNonVariantInterface(MscorlibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))) |
48 | { |
49 | DefineFullyQualifiedNameForClassW() |
50 | COMPlusThrow(kApplicationException, |
51 | IDS_EE_ICUSTOMMARSHALERNOTIMPL, |
52 | GetFullyQualifiedNameForClassW(hndCustomMarshalerType.GetMethodTable())); |
53 | } |
54 | |
55 | // Determine if this type is a value class. |
56 | m_bDataIsByValue = m_hndManagedType.GetMethodTable()->IsValueType(); |
57 | |
58 | // Custom marshalling of value classes is not currently supported. |
59 | if (m_bDataIsByValue) |
60 | COMPlusThrow(kNotSupportedException, W("NotSupported_ValueClassCM" )); |
61 | |
62 | #ifndef CROSSGEN_COMPILE |
63 | // Run the <clinit> on the marshaler since it might not have run yet. |
64 | hndCustomMarshalerType.GetMethodTable()->EnsureInstanceActive(); |
65 | hndCustomMarshalerType.GetMethodTable()->CheckRunClassInitThrowing(); |
66 | |
67 | // Create a COM+ string that will contain the string cookie. |
68 | STRINGREF CookieStringObj = StringObject::NewString(strCookie, cCookieStrBytes); |
69 | GCPROTECT_BEGIN(CookieStringObj); |
70 | #endif |
71 | |
72 | // Load the method desc's for all the methods in the ICustomMarshaler interface. |
73 | m_pMarshalNativeToManagedMD = GetCustomMarshalerMD(CustomMarshalerMethods_MarshalNativeToManaged, hndCustomMarshalerType); |
74 | m_pMarshalManagedToNativeMD = GetCustomMarshalerMD(CustomMarshalerMethods_MarshalManagedToNative, hndCustomMarshalerType); |
75 | m_pCleanUpNativeDataMD = GetCustomMarshalerMD(CustomMarshalerMethods_CleanUpNativeData, hndCustomMarshalerType); |
76 | m_pCleanUpManagedDataMD = GetCustomMarshalerMD(CustomMarshalerMethods_CleanUpManagedData, hndCustomMarshalerType); |
77 | |
78 | // Load the method desc for the static method to retrieve the instance. |
79 | MethodDesc *pGetCustomMarshalerMD = GetCustomMarshalerMD(CustomMarshalerMethods_GetInstance, hndCustomMarshalerType); |
80 | |
81 | // If the GetInstance method is generic, get an instantiating stub for it - |
82 | // the CallDescr infrastructure doesn't know how to pass secret generic arguments. |
83 | if (pGetCustomMarshalerMD->RequiresInstMethodTableArg()) |
84 | { |
85 | pGetCustomMarshalerMD = MethodDesc::FindOrCreateAssociatedMethodDesc( |
86 | pGetCustomMarshalerMD, |
87 | hndCustomMarshalerType.GetMethodTable(), |
88 | FALSE, // forceBoxedEntryPoint |
89 | Instantiation(), // methodInst |
90 | FALSE, // allowInstParam |
91 | FALSE); // forceRemotableMethod |
92 | |
93 | _ASSERTE(!pGetCustomMarshalerMD->RequiresInstMethodTableArg()); |
94 | } |
95 | |
96 | #ifndef CROSSGEN_COMPILE |
97 | MethodDescCallSite getCustomMarshaler(pGetCustomMarshalerMD, (OBJECTREF*)&CookieStringObj); |
98 | |
99 | pGetCustomMarshalerMD->EnsureActive(); |
100 | |
101 | // Prepare the arguments that will be passed to GetCustomMarshaler. |
102 | ARG_SLOT GetCustomMarshalerArgs[] = { |
103 | ObjToArgSlot(CookieStringObj) |
104 | }; |
105 | |
106 | // Call the GetCustomMarshaler method to retrieve the custom marshaler to use. |
107 | OBJECTREF CustomMarshalerObj = getCustomMarshaler.Call_RetOBJECTREF(GetCustomMarshalerArgs); |
108 | if (!CustomMarshalerObj) |
109 | { |
110 | DefineFullyQualifiedNameForClassW() |
111 | COMPlusThrow(kApplicationException, |
112 | IDS_EE_NOCUSTOMMARSHALER, |
113 | GetFullyQualifiedNameForClassW(hndCustomMarshalerType.GetMethodTable())); |
114 | } |
115 | m_hndCustomMarshaler = pDomain->CreateHandle(CustomMarshalerObj); |
116 | |
117 | // Retrieve the size of the native data. |
118 | if (m_bDataIsByValue) |
119 | { |
120 | // <TODO>@TODO(DM): Call GetNativeDataSize() to retrieve the size of the native data.</TODO> |
121 | _ASSERTE(!"Value classes are not yet supported by the custom marshaler!" ); |
122 | } |
123 | else |
124 | { |
125 | m_NativeSize = sizeof(void *); |
126 | } |
127 | |
128 | GCPROTECT_END(); |
129 | #endif |
130 | } |
131 | |
132 | |
133 | CustomMarshalerInfo::~CustomMarshalerInfo() |
134 | { |
135 | WRAPPER_NO_CONTRACT; |
136 | #ifndef CROSSGEN_COMPILE |
137 | if (m_hndCustomMarshaler) |
138 | { |
139 | DestroyHandle(m_hndCustomMarshaler); |
140 | m_hndCustomMarshaler = NULL; |
141 | } |
142 | #endif |
143 | } |
144 | |
145 | |
146 | void *CustomMarshalerInfo::operator new(size_t size, LoaderHeap *pHeap) |
147 | { |
148 | CONTRACTL |
149 | { |
150 | THROWS; |
151 | GC_NOTRIGGER; |
152 | MODE_ANY; |
153 | INJECT_FAULT(COMPlusThrowOM()); |
154 | PRECONDITION(CheckPointer(pHeap)); |
155 | } |
156 | CONTRACTL_END; |
157 | |
158 | return pHeap->AllocMem(S_SIZE_T(sizeof(CustomMarshalerInfo))); |
159 | } |
160 | |
161 | |
162 | void CustomMarshalerInfo::operator delete(void *pMem) |
163 | { |
164 | // Instances of this class are always allocated on the loader heap so |
165 | // the delete operator has nothing to do. |
166 | LIMITED_METHOD_CONTRACT; |
167 | } |
168 | |
169 | #ifndef CROSSGEN_COMPILE |
170 | OBJECTREF CustomMarshalerInfo::InvokeMarshalNativeToManagedMeth(void *pNative) |
171 | { |
172 | CONTRACTL |
173 | { |
174 | THROWS; |
175 | GC_TRIGGERS; |
176 | MODE_COOPERATIVE; |
177 | PRECONDITION(CheckPointer(pNative, NULL_OK)); |
178 | } |
179 | CONTRACTL_END; |
180 | |
181 | if (!pNative) |
182 | return NULL; |
183 | |
184 | MethodDescCallSite marshalNativeToManaged(m_pMarshalNativeToManagedMD, m_hndCustomMarshaler); |
185 | |
186 | ARG_SLOT Args[] = { |
187 | ObjToArgSlot(ObjectFromHandle(m_hndCustomMarshaler)), |
188 | PtrToArgSlot(pNative) |
189 | }; |
190 | |
191 | return marshalNativeToManaged.Call_RetOBJECTREF(Args); |
192 | } |
193 | |
194 | |
195 | void *CustomMarshalerInfo::InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj) |
196 | { |
197 | CONTRACTL |
198 | { |
199 | THROWS; |
200 | GC_TRIGGERS; |
201 | MODE_COOPERATIVE; |
202 | } |
203 | CONTRACTL_END; |
204 | |
205 | void *RetVal = NULL; |
206 | |
207 | if (!MngObj) |
208 | return NULL; |
209 | |
210 | GCPROTECT_BEGIN (MngObj); |
211 | MethodDescCallSite marshalManagedToNative(m_pMarshalManagedToNativeMD, m_hndCustomMarshaler); |
212 | |
213 | ARG_SLOT Args[] = { |
214 | ObjToArgSlot(ObjectFromHandle(m_hndCustomMarshaler)), |
215 | ObjToArgSlot(MngObj) |
216 | }; |
217 | |
218 | RetVal = marshalManagedToNative.Call_RetLPVOID(Args); |
219 | GCPROTECT_END (); |
220 | |
221 | return RetVal; |
222 | } |
223 | |
224 | |
225 | void CustomMarshalerInfo::InvokeCleanUpNativeMeth(void *pNative) |
226 | { |
227 | CONTRACTL |
228 | { |
229 | THROWS; |
230 | GC_TRIGGERS; |
231 | MODE_COOPERATIVE; |
232 | PRECONDITION(CheckPointer(pNative, NULL_OK)); |
233 | } |
234 | CONTRACTL_END; |
235 | |
236 | if (!pNative) |
237 | return; |
238 | |
239 | MethodDescCallSite cleanUpNativeData(m_pCleanUpNativeDataMD, m_hndCustomMarshaler); |
240 | |
241 | ARG_SLOT Args[] = { |
242 | ObjToArgSlot(ObjectFromHandle(m_hndCustomMarshaler)), |
243 | PtrToArgSlot(pNative) |
244 | }; |
245 | |
246 | cleanUpNativeData.Call(Args); |
247 | } |
248 | |
249 | |
250 | void CustomMarshalerInfo::InvokeCleanUpManagedMeth(OBJECTREF MngObj) |
251 | { |
252 | CONTRACTL |
253 | { |
254 | THROWS; |
255 | GC_TRIGGERS; |
256 | MODE_COOPERATIVE; |
257 | } |
258 | CONTRACTL_END; |
259 | |
260 | if (!MngObj) |
261 | return; |
262 | |
263 | GCPROTECT_BEGIN (MngObj); |
264 | MethodDescCallSite cleanUpManagedData(m_pCleanUpManagedDataMD, m_hndCustomMarshaler); |
265 | |
266 | ARG_SLOT Args[] = { |
267 | ObjToArgSlot(ObjectFromHandle(m_hndCustomMarshaler)), |
268 | ObjToArgSlot(MngObj) |
269 | }; |
270 | |
271 | cleanUpManagedData.Call(Args); |
272 | GCPROTECT_END (); |
273 | } |
274 | |
275 | #endif // CROSSGEN_COMPILE |
276 | MethodDesc *CustomMarshalerInfo::GetCustomMarshalerMD(EnumCustomMarshalerMethods Method, TypeHandle hndCustomMarshalertype) |
277 | { |
278 | CONTRACTL |
279 | { |
280 | THROWS; |
281 | GC_TRIGGERS; |
282 | MODE_COOPERATIVE; |
283 | } |
284 | CONTRACTL_END; |
285 | |
286 | |
287 | MethodTable *pMT = hndCustomMarshalertype.AsMethodTable(); |
288 | |
289 | _ASSERTE(pMT->CanCastToNonVariantInterface(MscorlibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))); |
290 | |
291 | MethodDesc *pMD = NULL; |
292 | |
293 | switch (Method) |
294 | { |
295 | case CustomMarshalerMethods_MarshalNativeToManaged: |
296 | pMD = pMT->GetMethodDescForInterfaceMethod( |
297 | MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_NATIVE_TO_MANAGED), |
298 | TRUE /* throwOnConflict */); |
299 | break; |
300 | case CustomMarshalerMethods_MarshalManagedToNative: |
301 | pMD = pMT->GetMethodDescForInterfaceMethod( |
302 | MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_MANAGED_TO_NATIVE), |
303 | TRUE /* throwOnConflict */); |
304 | break; |
305 | case CustomMarshalerMethods_CleanUpNativeData: |
306 | pMD = pMT->GetMethodDescForInterfaceMethod( |
307 | MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_NATIVE_DATA), |
308 | TRUE /* throwOnConflict */); |
309 | break; |
310 | |
311 | case CustomMarshalerMethods_CleanUpManagedData: |
312 | pMD = pMT->GetMethodDescForInterfaceMethod( |
313 | MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_MANAGED_DATA), |
314 | TRUE /* throwOnConflict */); |
315 | break; |
316 | case CustomMarshalerMethods_GetNativeDataSize: |
317 | pMD = pMT->GetMethodDescForInterfaceMethod( |
318 | MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__GET_NATIVE_DATA_SIZE), |
319 | TRUE /* throwOnConflict */); |
320 | break; |
321 | case CustomMarshalerMethods_GetInstance: |
322 | // Must look this up by name since it's static |
323 | pMD = MemberLoader::FindMethod(pMT, "GetInstance" , &gsig_SM_Str_RetICustomMarshaler); |
324 | if (!pMD) |
325 | { |
326 | DefineFullyQualifiedNameForClassW() |
327 | COMPlusThrow(kApplicationException, |
328 | IDS_EE_GETINSTANCENOTIMPL, |
329 | GetFullyQualifiedNameForClassW(pMT)); |
330 | } |
331 | break; |
332 | default: |
333 | _ASSERTE(!"Unknown custom marshaler method" ); |
334 | } |
335 | |
336 | _ASSERTE(pMD && "Unable to find specified CustomMarshaler method" ); |
337 | |
338 | // Ensure that the value types in the signature are loaded. |
339 | MetaSig::EnsureSigValueTypesLoaded(pMD); |
340 | |
341 | // Return the specified method desc. |
342 | return pMD; |
343 | } |
344 | |
345 | #ifndef CROSSGEN_COMPILE |
346 | |
347 | //========================================================================== |
348 | // Implementation of the custom marshaler hashtable helper. |
349 | //========================================================================== |
350 | |
351 | EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey *pKey, BOOL bDeepCopy, void* pHeap) |
352 | { |
353 | CONTRACTL |
354 | { |
355 | NOTHROW; |
356 | GC_NOTRIGGER; |
357 | MODE_ANY; |
358 | INJECT_FAULT(return NULL;); |
359 | } |
360 | CONTRACTL_END; |
361 | |
362 | EEHashEntry_t *pEntry; |
363 | |
364 | if (bDeepCopy) |
365 | { |
366 | S_SIZE_T cbEntry = S_SIZE_T(sizeof(EEHashEntry) - 1 + sizeof(EECMHelperHashtableKey)); |
367 | cbEntry += S_SIZE_T(pKey->GetMarshalerTypeNameByteCount()); |
368 | cbEntry += S_SIZE_T(pKey->GetCookieStringByteCount()); |
369 | cbEntry += S_SIZE_T(pKey->GetMarshalerInstantiation().GetNumArgs()) * S_SIZE_T(sizeof(LPVOID)); |
370 | |
371 | if (cbEntry.IsOverflow()) |
372 | return NULL; |
373 | |
374 | pEntry = (EEHashEntry_t *) new (nothrow) BYTE[cbEntry.Value()]; |
375 | if (!pEntry) |
376 | return NULL; |
377 | |
378 | EECMHelperHashtableKey *pEntryKey = (EECMHelperHashtableKey *) pEntry->Key; |
379 | pEntryKey->m_cMarshalerTypeNameBytes = pKey->GetMarshalerTypeNameByteCount(); |
380 | pEntryKey->m_strMarshalerTypeName = (LPSTR) pEntry->Key + sizeof(EECMHelperHashtableKey); |
381 | pEntryKey->m_cCookieStrBytes = pKey->GetCookieStringByteCount(); |
382 | pEntryKey->m_strCookie = (LPSTR) pEntry->Key + sizeof(EECMHelperHashtableKey) + pEntryKey->m_cMarshalerTypeNameBytes; |
383 | pEntryKey->m_Instantiation = Instantiation( |
384 | (TypeHandle *) (pEntryKey->m_strCookie + pEntryKey->m_cCookieStrBytes), |
385 | pKey->GetMarshalerInstantiation().GetNumArgs()); |
386 | memcpy((void*)pEntryKey->m_strMarshalerTypeName, pKey->GetMarshalerTypeName(), pKey->GetMarshalerTypeNameByteCount()); |
387 | memcpy((void*)pEntryKey->m_strCookie, pKey->GetCookieString(), pKey->GetCookieStringByteCount()); |
388 | memcpy((void*)pEntryKey->m_Instantiation.GetRawArgs(), pKey->GetMarshalerInstantiation().GetRawArgs(), |
389 | pEntryKey->m_Instantiation.GetNumArgs() * sizeof(LPVOID)); |
390 | } |
391 | else |
392 | { |
393 | pEntry = (EEHashEntry_t *) |
394 | new (nothrow) BYTE[sizeof(EEHashEntry) - 1 + sizeof(EECMHelperHashtableKey)]; |
395 | if (!pEntry) |
396 | return NULL; |
397 | |
398 | EECMHelperHashtableKey *pEntryKey = (EECMHelperHashtableKey *) pEntry->Key; |
399 | pEntryKey->m_cMarshalerTypeNameBytes = pKey->GetMarshalerTypeNameByteCount(); |
400 | pEntryKey->m_strMarshalerTypeName = pKey->GetMarshalerTypeName(); |
401 | pEntryKey->m_cCookieStrBytes = pKey->GetCookieStringByteCount(); |
402 | pEntryKey->m_strCookie = pKey->GetCookieString(); |
403 | pEntryKey->m_Instantiation = Instantiation(pKey->GetMarshalerInstantiation()); |
404 | } |
405 | |
406 | return pEntry; |
407 | } |
408 | |
409 | |
410 | void EECMHelperHashtableHelper::DeleteEntry(EEHashEntry_t *pEntry, void* pHeap) |
411 | { |
412 | CONTRACTL |
413 | { |
414 | NOTHROW; |
415 | GC_NOTRIGGER; |
416 | MODE_ANY; |
417 | PRECONDITION(CheckPointer(pEntry)); |
418 | } |
419 | CONTRACTL_END; |
420 | |
421 | delete[] (BYTE*)pEntry; |
422 | } |
423 | |
424 | |
425 | BOOL EECMHelperHashtableHelper::CompareKeys(EEHashEntry_t *pEntry, EECMHelperHashtableKey *pKey) |
426 | { |
427 | CONTRACTL |
428 | { |
429 | NOTHROW; |
430 | GC_NOTRIGGER; |
431 | MODE_ANY; |
432 | PRECONDITION(CheckPointer(pEntry)); |
433 | PRECONDITION(CheckPointer(pKey)); |
434 | } |
435 | CONTRACTL_END; |
436 | |
437 | EECMHelperHashtableKey *pEntryKey = (EECMHelperHashtableKey *) pEntry->Key; |
438 | |
439 | if (pEntryKey->GetMarshalerTypeNameByteCount() != pKey->GetMarshalerTypeNameByteCount()) |
440 | return FALSE; |
441 | |
442 | if (memcmp(pEntryKey->GetMarshalerTypeName(), pKey->GetMarshalerTypeName(), pEntryKey->GetMarshalerTypeNameByteCount()) != 0) |
443 | return FALSE; |
444 | |
445 | if (pEntryKey->GetCookieStringByteCount() != pKey->GetCookieStringByteCount()) |
446 | return FALSE; |
447 | |
448 | if (memcmp(pEntryKey->GetCookieString(), pKey->GetCookieString(), pEntryKey->GetCookieStringByteCount()) != 0) |
449 | return FALSE; |
450 | |
451 | DWORD dwNumTypeArgs = pEntryKey->GetMarshalerInstantiation().GetNumArgs(); |
452 | if (dwNumTypeArgs != pKey->GetMarshalerInstantiation().GetNumArgs()) |
453 | return FALSE; |
454 | |
455 | for (DWORD i = 0; i < dwNumTypeArgs; i++) |
456 | { |
457 | if (pEntryKey->GetMarshalerInstantiation()[i] != pKey->GetMarshalerInstantiation()[i]) |
458 | return FALSE; |
459 | } |
460 | |
461 | return TRUE; |
462 | } |
463 | |
464 | |
465 | DWORD EECMHelperHashtableHelper::Hash(EECMHelperHashtableKey *pKey) |
466 | { |
467 | WRAPPER_NO_CONTRACT; |
468 | |
469 | return (DWORD) |
470 | (HashBytes((const BYTE *) pKey->GetMarshalerTypeName(), pKey->GetMarshalerTypeNameByteCount()) + |
471 | HashBytes((const BYTE *) pKey->GetCookieString(), pKey->GetCookieStringByteCount()) + |
472 | HashBytes((const BYTE *) pKey->GetMarshalerInstantiation().GetRawArgs(), pKey->GetMarshalerInstantiation().GetNumArgs() * sizeof(LPVOID))); |
473 | } |
474 | |
475 | |
476 | OBJECTREF CustomMarshalerHelper::InvokeMarshalNativeToManagedMeth(void *pNative) |
477 | { |
478 | WRAPPER_NO_CONTRACT; |
479 | return GetCustomMarshalerInfo()->InvokeMarshalNativeToManagedMeth(pNative); |
480 | } |
481 | |
482 | |
483 | void *CustomMarshalerHelper::InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj) |
484 | { |
485 | CONTRACTL |
486 | { |
487 | THROWS; |
488 | GC_TRIGGERS; |
489 | MODE_COOPERATIVE; |
490 | } |
491 | CONTRACTL_END; |
492 | |
493 | void *RetVal = NULL; |
494 | |
495 | GCPROTECT_BEGIN(MngObj) |
496 | { |
497 | CustomMarshalerInfo *pCMInfo = GetCustomMarshalerInfo(); |
498 | RetVal = pCMInfo->InvokeMarshalManagedToNativeMeth(MngObj); |
499 | } |
500 | GCPROTECT_END(); |
501 | |
502 | return RetVal; |
503 | } |
504 | |
505 | |
506 | void CustomMarshalerHelper::InvokeCleanUpNativeMeth(void *pNative) |
507 | { |
508 | CONTRACTL |
509 | { |
510 | THROWS; |
511 | GC_TRIGGERS; |
512 | MODE_COOPERATIVE; |
513 | } |
514 | CONTRACTL_END; |
515 | |
516 | OBJECTREF ExceptionObj = NULL; |
517 | GCPROTECT_BEGIN(ExceptionObj) |
518 | { |
519 | EX_TRY |
520 | { |
521 | GetCustomMarshalerInfo()->InvokeCleanUpNativeMeth(pNative); |
522 | } |
523 | EX_CATCH |
524 | { |
525 | ExceptionObj = GET_THROWABLE(); |
526 | } |
527 | EX_END_CATCH(SwallowAllExceptions); |
528 | |
529 | #ifdef MDA_SUPPORTED |
530 | if (ExceptionObj != NULL) |
531 | { |
532 | TypeHandle typeCustomMarshaler = GetCustomMarshalerInfo()->GetCustomMarshalerType(); |
533 | MDA_TRIGGER_ASSISTANT(MarshalCleanupError, ReportErrorCustomMarshalerCleanup(typeCustomMarshaler, &ExceptionObj)); |
534 | } |
535 | #endif |
536 | } |
537 | GCPROTECT_END(); |
538 | } |
539 | |
540 | |
541 | void CustomMarshalerHelper::InvokeCleanUpManagedMeth(OBJECTREF MngObj) |
542 | { |
543 | CONTRACTL |
544 | { |
545 | THROWS; |
546 | GC_TRIGGERS; |
547 | MODE_COOPERATIVE; |
548 | } |
549 | CONTRACTL_END; |
550 | |
551 | GCPROTECT_BEGIN(MngObj) |
552 | { |
553 | CustomMarshalerInfo *pCMInfo = GetCustomMarshalerInfo(); |
554 | pCMInfo->InvokeCleanUpManagedMeth(MngObj); |
555 | } |
556 | GCPROTECT_END(); |
557 | } |
558 | |
559 | |
560 | void *NonSharedCustomMarshalerHelper::operator new(size_t size, LoaderHeap *pHeap) |
561 | { |
562 | CONTRACTL |
563 | { |
564 | THROWS; |
565 | GC_NOTRIGGER; |
566 | MODE_ANY; |
567 | INJECT_FAULT(COMPlusThrowOM()); |
568 | PRECONDITION(CheckPointer(pHeap)); |
569 | } |
570 | CONTRACTL_END; |
571 | |
572 | return pHeap->AllocMem(S_SIZE_T(sizeof(NonSharedCustomMarshalerHelper))); |
573 | } |
574 | |
575 | |
576 | void NonSharedCustomMarshalerHelper::operator delete(void *pMem) |
577 | { |
578 | // Instances of this class are always allocated on the loader heap so |
579 | // the delete operator has nothing to do. |
580 | LIMITED_METHOD_CONTRACT; |
581 | } |
582 | |
583 | |
584 | SharedCustomMarshalerHelper::SharedCustomMarshalerHelper(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes) |
585 | : m_pAssembly(pAssembly) |
586 | , m_hndManagedType(hndManagedType) |
587 | , m_cMarshalerTypeNameBytes(cMarshalerTypeNameBytes) |
588 | , m_strMarshalerTypeName(strMarshalerTypeName) |
589 | , m_cCookieStrBytes(cCookieStrBytes) |
590 | , m_strCookie(strCookie) |
591 | { |
592 | WRAPPER_NO_CONTRACT; |
593 | } |
594 | |
595 | |
596 | void *SharedCustomMarshalerHelper::operator new(size_t size, LoaderHeap *pHeap) |
597 | { |
598 | CONTRACTL |
599 | { |
600 | THROWS; |
601 | GC_NOTRIGGER; |
602 | MODE_ANY; |
603 | INJECT_FAULT(COMPlusThrowOM()); |
604 | PRECONDITION(CheckPointer(pHeap)); |
605 | } |
606 | CONTRACTL_END; |
607 | |
608 | return pHeap->AllocMem(S_SIZE_T(sizeof(SharedCustomMarshalerHelper))); |
609 | } |
610 | |
611 | |
612 | void SharedCustomMarshalerHelper::operator delete(void *pMem) |
613 | { |
614 | // Instances of this class are always allocated on the loader heap so |
615 | // the delete operator has nothing to do. |
616 | LIMITED_METHOD_CONTRACT; |
617 | } |
618 | |
619 | |
620 | CustomMarshalerInfo *SharedCustomMarshalerHelper::GetCustomMarshalerInfo() |
621 | { |
622 | CONTRACTL |
623 | { |
624 | THROWS; |
625 | GC_TRIGGERS; |
626 | MODE_COOPERATIVE; |
627 | } |
628 | CONTRACTL_END; |
629 | |
630 | // Retrieve the marshalling data for the current app domain. |
631 | EEMarshalingData *pMarshalingData = GetThread()->GetDomain()->GetMarshalingData(); |
632 | |
633 | // Retrieve the custom marshaling information for the current shared custom |
634 | // marshaling helper. |
635 | return pMarshalingData->GetCustomMarshalerInfo(this); |
636 | } |
637 | |
638 | |
639 | #endif // CROSSGEN_COMPILE |
640 | |
641 | |