@@ -2813,36 +2813,88 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
28132813                    int  opcode = *ip;
28142814                    int  dreg = ip[1 ];
28152815                    int  sreg = ip[2 ];
2816-                     HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper<HELPER_FTN_BOX_UNBOX>(pMethod, ip[3 ]);
28172816                    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+                     }
28182835
28192836                    //  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);
28232838
28242839                    ip += 5 ;
28252840                    break ;
28262841                }
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);
28272849
2850+                     ip += 4 ;
2851+                     break ;
2852+                 }
28282853                case  INTOP_UNBOX_ANY_GENERIC:
28292854                {
28302855                    int  opcode = *ip;
28312856                    int  dreg = ip[1 ];
28322857                    int  sreg = ip[3 ];
28332858                    InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems [ip[5 ]];
28342859                    MethodTable *pMTBoxedObj = (MethodTable*)DoGenericLookup (LOCAL_VAR (ip[2 ], void *), pLookup);
2860+                     Object *src = LOCAL_VAR (sreg, Object*);
28352861
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+                     }
28372879
28382880                    //  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);
28422882
28432883                    ip += 6 ;
28442884                    break ;
28452885                }
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+                 }
28462898                case  INTOP_NEWARR:
28472899                {
28482900                    int32_t  length = LOCAL_VAR (ip[2 ], int32_t );
0 commit comments