@@ -2813,36 +2813,88 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
2813
2813
int opcode = *ip;
2814
2814
int dreg = ip[1 ];
2815
2815
int sreg = ip[2 ];
2816
- HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper<HELPER_FTN_BOX_UNBOX>(pMethod, ip[3 ]);
2817
2816
MethodTable *pMT = (MethodTable*)pMethod->pDataItems [ip[4 ]];
2817
+ Object *src = LOCAL_VAR (sreg, Object*);
2818
+
2819
+ MethodDesc *pILTargetMethod = NULL ;
2820
+ HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper<HELPER_FTN_BOX_UNBOX>(pMethod, ip[3 ], &pILTargetMethod);
2821
+ if (pILTargetMethod != NULL )
2822
+ {
2823
+ callArgsOffset = pMethod->allocaSize ;
2824
+ returnOffset = dreg;
2825
+
2826
+ // Pass arguments to the target method
2827
+ LOCAL_VAR (callArgsOffset, void *) = pMT;
2828
+ LOCAL_VAR (callArgsOffset + INTERP_STACK_SLOT_SIZE, void *) = src;
2829
+
2830
+ targetMethod = pILTargetMethod;
2831
+ ip += 5 ;
2832
+
2833
+ goto CALL_INTERP_METHOD;
2834
+ }
2818
2835
2819
2836
// private static ref byte Unbox(MethodTable* toTypeHnd, object obj)
2820
- Object *src = LOCAL_VAR (sreg, Object*);
2821
- void *unboxedData = helper (pMT, src);
2822
- CopyValueClassUnchecked (LOCAL_VAR_ADDR (dreg, void ), unboxedData, pMT);
2837
+ LOCAL_VAR (dreg, void *) = helper (pMT, src);
2823
2838
2824
2839
ip += 5 ;
2825
2840
break ;
2826
2841
}
2842
+ case INTOP_UNBOX_END:
2843
+ {
2844
+ MethodTable *pMT = (MethodTable*)pMethod->pDataItems [ip[3 ]];
2845
+ void *dest = LOCAL_VAR_ADDR (ip[1 ], void );
2846
+ void *src = LOCAL_VAR (ip[2 ], void *);
2847
+ NULL_CHECK (dest);
2848
+ CopyValueClassUnchecked (dest, src, pMT);
2827
2849
2850
+ ip += 4 ;
2851
+ break ;
2852
+ }
2828
2853
case INTOP_UNBOX_ANY_GENERIC:
2829
2854
{
2830
2855
int opcode = *ip;
2831
2856
int dreg = ip[1 ];
2832
2857
int sreg = ip[3 ];
2833
2858
InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems [ip[5 ]];
2834
2859
MethodTable *pMTBoxedObj = (MethodTable*)DoGenericLookup (LOCAL_VAR (ip[2 ], void *), pLookup);
2860
+ Object *src = LOCAL_VAR (sreg, Object*);
2835
2861
2836
- HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper<HELPER_FTN_BOX_UNBOX>(pMethod, ip[4 ]);
2862
+ MethodDesc *pILTargetMethod = NULL ;
2863
+ HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper<HELPER_FTN_BOX_UNBOX>(pMethod, ip[4 ], &pILTargetMethod);
2864
+
2865
+ if (pILTargetMethod != NULL )
2866
+ {
2867
+ callArgsOffset = pMethod->allocaSize ;
2868
+ returnOffset = dreg;
2869
+
2870
+ // Pass arguments to the target method
2871
+ LOCAL_VAR (callArgsOffset, void *) = pMTBoxedObj;
2872
+ LOCAL_VAR (callArgsOffset + INTERP_STACK_SLOT_SIZE, void *) = src;
2873
+
2874
+ targetMethod = pILTargetMethod;
2875
+ ip += 6 ;
2876
+
2877
+ goto CALL_INTERP_METHOD;
2878
+ }
2837
2879
2838
2880
// private static ref byte Unbox(MethodTable* toTypeHnd, object obj)
2839
- Object *src = LOCAL_VAR (sreg, Object*);
2840
- void *unboxedData = helper (pMTBoxedObj, src);
2841
- CopyValueClassUnchecked (LOCAL_VAR_ADDR (dreg, void ), unboxedData, pMTBoxedObj->IsNullable () ? pMTBoxedObj->GetInstantiation ()[0 ].AsMethodTable () : pMTBoxedObj);
2881
+ LOCAL_VAR (dreg, void *) = helper (pMTBoxedObj, src);
2842
2882
2843
2883
ip += 6 ;
2844
2884
break ;
2845
2885
}
2886
+ case INTOP_UNBOX_END_GENERIC:
2887
+ {
2888
+ InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems [ip[4 ]];
2889
+ MethodTable *pMT = (MethodTable*)DoGenericLookup (LOCAL_VAR (ip[2 ], void *), pLookup);
2890
+ void *dest = LOCAL_VAR_ADDR (ip[1 ], void );
2891
+ void *src = LOCAL_VAR (ip[3 ], void *);
2892
+ NULL_CHECK (dest);
2893
+ CopyValueClassUnchecked (dest, src, pMT->IsNullable () ? pMT->GetInstantiation ()[0 ].AsMethodTable () : pMT);
2894
+
2895
+ ip += 5 ;
2896
+ break ;
2897
+ }
2846
2898
case INTOP_NEWARR:
2847
2899
{
2848
2900
int32_t length = LOCAL_VAR (ip[2 ], int32_t );
0 commit comments