diff options
author | Atsushi Kanamori <AtsushiKan@users.noreply.github.com> | 2018-04-23 13:42:24 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-23 13:42:24 -0700 |
commit | 5a42b8c7348ba7dfa0dbf423d36245570488c888 (patch) | |
tree | c35278add0c8c8ab6fd9d2063f1d37494c5feb7e /src/vm/invokeutil.cpp | |
parent | 72dd7f2146cee213babb18378130e4375442aca1 (diff) | |
download | coreclr-5a42b8c7348ba7dfa0dbf423d36245570488c888.tar.gz coreclr-5a42b8c7348ba7dfa0dbf423d36245570488c888.tar.bz2 coreclr-5a42b8c7348ba7dfa0dbf423d36245570488c888.zip |
Enable Invoke and GetValue for ref-returning members (#17732)
* Reapply https://github.com/dotnet/coreclr/pull/17639
* tryagain-wip 4/23/2018 7:27:37 AM - Fix Invoke of enum-returning methods
* Assert for refbufargs implying valuetype
* Catch ref to void in managed layer
Diffstat (limited to 'src/vm/invokeutil.cpp')
-rw-r--r-- | src/vm/invokeutil.cpp | 57 |
1 files changed, 16 insertions, 41 deletions
diff --git a/src/vm/invokeutil.cpp b/src/vm/invokeutil.cpp index 170b0da6d6..a45e81b262 100644 --- a/src/vm/invokeutil.cpp +++ b/src/vm/invokeutil.cpp @@ -649,9 +649,14 @@ void InvokeUtil::ValidField(TypeHandle th, OBJECTREF* value) COMPlusThrow(kArgumentException,W("Arg_ObjObj")); } -// InternalCreateObject -// This routine will create the specified object from the value -OBJECTREF InvokeUtil::CreateObject(TypeHandle th, void * pValue) { +// +// CreateObjectAfterInvoke +// This routine will create the specified object from the value returned by the Invoke target. +// +// This does not handle the ELEMENT_TYPE_VALUETYPE case. The caller must preallocate the box object and +// copy the value type into it afterward. +// +OBJECTREF InvokeUtil::CreateObjectAfterInvoke(TypeHandle th, void * pValue) { CONTRACTL { THROWS; GC_TRIGGERS; @@ -663,9 +668,11 @@ OBJECTREF InvokeUtil::CreateObject(TypeHandle th, void * pValue) { CONTRACTL_END; CorElementType type = th.GetSignatureCorElementType(); - MethodTable *pMT = NULL; OBJECTREF obj = NULL; + // WARNING: pValue can be an inner reference into a managed object and it is not protected from GC. You must do nothing that + // triggers a GC until the all the data it points to has been captured in a GC-protected location. + // Handle the non-table types switch (type) { case ELEMENT_TYPE_VOID: @@ -677,18 +684,6 @@ OBJECTREF InvokeUtil::CreateObject(TypeHandle th, void * pValue) { break; } - case ELEMENT_TYPE_FNPTR: - pMT = MscorlibBinder::GetElementType(ELEMENT_TYPE_I); - goto PrimitiveType; - - case ELEMENT_TYPE_VALUETYPE: - { - _ASSERTE(!th.IsTypeDesc()); - pMT = th.AsMethodTable(); - obj = pMT->Box(pValue); - break; - } - case ELEMENT_TYPE_CLASS: // Class case ELEMENT_TYPE_SZARRAY: // Single Dim, Zero case ELEMENT_TYPE_ARRAY: // General Array @@ -698,35 +693,15 @@ OBJECTREF InvokeUtil::CreateObject(TypeHandle th, void * pValue) { obj = *(OBJECTREF *)pValue; break; - case ELEMENT_TYPE_BOOLEAN: // boolean - case ELEMENT_TYPE_I1: // byte - case ELEMENT_TYPE_U1: - case ELEMENT_TYPE_I2: // short - case ELEMENT_TYPE_U2: - case ELEMENT_TYPE_CHAR: // char - case ELEMENT_TYPE_I4: // int - case ELEMENT_TYPE_U4: - case ELEMENT_TYPE_I8: // long - case ELEMENT_TYPE_U8: - case ELEMENT_TYPE_R4: // float - case ELEMENT_TYPE_R8: // double - case ELEMENT_TYPE_I: - case ELEMENT_TYPE_U: - _ASSERTE(!th.IsTypeDesc()); - pMT = th.AsMethodTable(); - PrimitiveType: + case ELEMENT_TYPE_FNPTR: { - // Don't use MethodTable::Box here for perf reasons - PREFIX_ASSUME(pMT != NULL); - obj = AllocateObject(pMT); - DWORD size = pMT->GetNumInstanceFieldBytes(); - memcpyNoGCRefs(obj->UnBox(), pValue, size); + LPVOID capturedValue = *(LPVOID*)pValue; + INDEBUG(pValue = (LPVOID)0xcccccccc); // We're about to allocate a GC object - can no longer trust pValue + obj = AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_I)); + *(LPVOID*)(obj->UnBox()) = capturedValue; } break; - case ELEMENT_TYPE_BYREF: - COMPlusThrow(kNotSupportedException, W("NotSupported_ByRefReturn")); - case ELEMENT_TYPE_END: default: _ASSERTE(!"Unknown Type"); COMPlusThrow(kNotSupportedException); |