1515#include " reflectioninvocation.h"
1616#include " runtimehandles.h"
1717#include " typestring.h"
18+ #include " callhelpers.h"
1819
1920static TypeHandle GetTypeForEnum (LPCUTF8 szEnumName, COUNT_T cbEnumName, Assembly* pAssembly)
2021{
@@ -915,23 +916,35 @@ extern "C" void QCALLTYPE CustomAttribute_CreateCustomAttributeInstance(
915916 MethodDesc* pCtorMD = ((REFLECTMETHODREF)pMethod.Get ())->GetMethod ();
916917 TypeHandle th = ((REFLECTCLASSBASEREF)pCaType.Get ())->GetType ();
917918
918- MethodDescCallSite ctorCallSite (pCtorMD, th);
919- MetaSig* pSig = ctorCallSite. GetMetaSig () ;
919+ MetaSig ctorSig (pCtorMD, th);
920+ MetaSig* pSig = &ctorSig ;
920921 BYTE* pBlob = *ppBlob;
921922
922- // get the number of arguments and allocate an array for the args
923- ARG_SLOT *args = NULL ;
924- UINT cArgs = pSig->NumFixedArgs () + 1 ; // make room for the this pointer
925- UINT i = 1 ; // used to flag that we actually get the right number of arg from the blob
923+ UINT cArgs = pSig->NumFixedArgs ();
924+ UINT i = 0 ;
926925
927- args = (ARG_SLOT*)_alloca (cArgs * sizeof (ARG_SLOT));
928- memset ((void *)args, 0 , cArgs * sizeof (ARG_SLOT));
929-
930- OBJECTREF *argToProtect = (OBJECTREF*)_alloca (cArgs * sizeof (OBJECTREF));
931- memset ((void *)argToProtect, 0 , cArgs * sizeof (OBJECTREF));
932-
933- // load the this pointer
934- argToProtect[0 ] = th.GetMethodTable ()->Allocate (); // this is the value to return after the ctor invocation
926+ struct
927+ {
928+ OBJECTREF ctorArgs;
929+ OBJECTREF ctorArgIsValueTypeFlags;
930+ OBJECTREF ctorObj;
931+ OBJECTREF ctorArgsObj;
932+ OBJECTREF ctorTarget;
933+ OBJECTREF ctorResult;
934+ } gc;
935+ gc.ctorArgs = NULL ;
936+ gc.ctorArgIsValueTypeFlags = NULL ;
937+ gc.ctorObj = NULL ;
938+ gc.ctorArgsObj = NULL ;
939+ gc.ctorTarget = NULL ;
940+ gc.ctorResult = NULL ;
941+ GCPROTECT_BEGIN (gc);
942+
943+ gc.ctorArgs = (OBJECTREF)AllocateObjectArray (cArgs, g_pObjectClass);
944+ gc.ctorArgIsValueTypeFlags = (OBJECTREF)(U1ARRAYREF)AllocatePrimitiveArray (ELEMENT_TYPE_U1, cArgs);
945+ gc.ctorTarget = th.GetMethodTable ()->Allocate ();
946+
947+ BYTE* argIsValueTypeFlags = ((U1ARRAYREF)gc.ctorArgIsValueTypeFlags )->GetDataPtr ();
935948
936949 if (pBlob)
937950 {
@@ -947,44 +960,53 @@ extern "C" void QCALLTYPE CustomAttribute_CreateCustomAttributeInstance(
947960 pBlob += 2 ;
948961 }
949962
950- if (cArgs > 1 )
963+ if (cArgs > 0 )
951964 {
952- GCPROTECT_ARRAY_BEGIN (*argToProtect, cArgs);
965+ // loop through the args
966+ for (i = 0 ; i < cArgs; i++)
953967 {
954- // loop through the args
955- for (i = 1 ; i < cArgs; i++) {
956- CorElementType type = pSig->NextArg ();
957- if (type == ELEMENT_TYPE_END)
958- break ;
959- BOOL bObjectCreated = FALSE ;
960- TypeHandle th = pSig->GetLastTypeHandleThrowing ();
961- if (th.IsArray ())
962- // get the array element
963- th = th.GetArrayElementTypeHandle ();
964- ARG_SLOT data = GetDataFromBlob (pCtorMD->GetAssembly (), (CorSerializationType)type, th, &pBlob, pEndBlob, pModule, &bObjectCreated);
965- if (bObjectCreated)
966- argToProtect[i] = ArgSlotToObj (data);
967- else
968- args[i] = data;
968+ CorElementType type = pSig->NextArg ();
969+ if (type == ELEMENT_TYPE_END)
970+ break ;
971+
972+ BOOL bObjectCreated = FALSE ;
973+ TypeHandle argType = pSig->GetLastTypeHandleThrowing ();
974+ if (argType.IsArray ())
975+ argType = argType.GetArrayElementTypeHandle ();
976+
977+ argIsValueTypeFlags[i] = argType.IsValueType () ? 1 : 0 ;
978+
979+ ARG_SLOT data = GetDataFromBlob (
980+ pCtorMD->GetAssembly (),
981+ (CorSerializationType)type,
982+ argType,
983+ &pBlob,
984+ pEndBlob,
985+ pModule,
986+ &bObjectCreated);
987+
988+ OBJECTREF argObj = NULL ;
989+ if (bObjectCreated)
990+ {
991+ argObj = ArgSlotToObj (data);
969992 }
970- }
971- GCPROTECT_END ();
972-
973- // We have borrowed the signature from MethodDescCallSite. We have to put it back into the initial position
974- // because of that's where MethodDescCallSite expects to find it below.
975- pSig->Reset ();
976-
977- for (i = 1 ; i < cArgs; i++)
978- {
979- if (argToProtect[i] != NULL )
993+ else
980994 {
981- _ASSERTE (args[i] == (ARG_SLOT)NULL );
982- args[i] = ObjToArgSlot (argToProtect[i]);
995+ MethodTable* pMTValue = (type == ELEMENT_TYPE_VALUETYPE || type == ELEMENT_TYPE_CLASS)
996+ ? argType.GetMethodTable ()
997+ : CoreLibBinder::GetElementType (type);
998+
999+ _ASSERTE (pMTValue != NULL );
1000+ argObj = pMTValue->Box ((void *)ArgSlotEndiannessFixup (&data, pMTValue->GetNumInstanceFieldBytes ()));
9831001 }
1002+
1003+ ((PTRARRAYREF)gc.ctorArgs )->SetAt (i, argObj);
9841004 }
1005+
1006+ // Reset signature enumeration before we leave argument processing.
1007+ pSig->Reset ();
9851008 }
9861009 }
987- args[0 ] = ObjToArgSlot (argToProtect[0 ]);
9881010
9891011 if (i != cArgs)
9901012 COMPlusThrow (kCustomAttributeFormatException );
@@ -1009,12 +1031,31 @@ extern "C" void QCALLTYPE CustomAttribute_CreateCustomAttributeInstance(
10091031 if (*pcNamedArgs == 0 && pBlob != pEndBlob)
10101032 COMPlusThrow (kCustomAttributeFormatException );
10111033
1012- // make the invocation to the ctor
1013- result.Set (ArgSlotToObj (args[0 ]));
1014- if (pCtorMD->GetMethodTable ()->IsValueType ())
1015- args[0 ] = PtrToArgSlot (OBJECTREFToObject (result.Get ())->UnBox ());
1034+ gc.ctorObj = pMethod.Get ();
1035+ gc.ctorArgsObj = gc.ctorArgs ;
1036+ PCODE ctorEntryPoint = pCtorMD->GetSingleCallableAddrOfCode ();
1037+
1038+ struct NativeCtorInvokeContract
1039+ {
1040+ OBJECTREF* ctorArgs;
1041+ OBJECTREF* argIsValueType;
1042+ INT32 argCount;
1043+ OBJECTREF* ctorTarget;
1044+ PCODE ctorEntryPoint;
1045+ } contract;
1046+
1047+ contract.ctorArgs = &gc.ctorArgsObj ;
1048+ contract.argIsValueType = &gc.ctorArgIsValueTypeFlags ;
1049+ contract.argCount = (INT32)cArgs;
1050+ contract.ctorTarget = &gc.ctorTarget ;
1051+ contract.ctorEntryPoint = ctorEntryPoint;
1052+
1053+ UnmanagedCallersOnlyCaller invokeCustomAttributeCtor (METHOD__CUSTOMATTRIBUTE__INVOKE_CUSTOM_ATTRIBUTE_CTOR);
1054+ invokeCustomAttributeCtor.InvokeThrowing (&gc.ctorObj , &contract, &gc.ctorResult );
10161055
1017- ctorCallSite.CallWithValueTypes (args);
1056+ result.Set (gc.ctorResult );
1057+
1058+ GCPROTECT_END ();
10181059
10191060 END_QCALL;
10201061}
0 commit comments