@@ -2311,7 +2311,7 @@ int InterpCompiler::EmitGenericHandleAsVar(const CORINFO_GENERICHANDLE_RESULT &e
23112311 return resultVar;
23122312}
23132313
2314- void InterpCompiler::EmitCall (CORINFO_RESOLVED_TOKEN* constrainedClass , bool readonly, bool tailcall, bool newObj, bool isCalli)
2314+ void InterpCompiler::EmitCall (CORINFO_RESOLVED_TOKEN* pConstrainedToken , bool readonly, bool tailcall, bool newObj, bool isCalli)
23152315{
23162316 uint32_t token = getU4LittleEndian (m_ip + 1 );
23172317 bool isVirtual = (*m_ip == CEE_CALLVIRT);
@@ -2341,19 +2341,38 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* constrainedClass, bool rea
23412341 }
23422342 else
23432343 {
2344-
23452344 ResolveToken (token, newObj ? CORINFO_TOKENKIND_NewObj : CORINFO_TOKENKIND_Method, &resolvedCallToken);
2346-
2345+
23472346 CORINFO_CALLINFO_FLAGS flags = (CORINFO_CALLINFO_FLAGS)(CORINFO_CALLINFO_ALLOWINSTPARAM | CORINFO_CALLINFO_SECURITYCHECKS | CORINFO_CALLINFO_DISALLOW_STUB);
23482347 if (isVirtual)
23492348 flags = (CORINFO_CALLINFO_FLAGS)(flags | CORINFO_CALLINFO_CALLVIRT);
23502349
2351- m_compHnd->getCallInfo (&resolvedCallToken, constrainedClass , m_methodInfo->ftn , flags, &callInfo);
2350+ m_compHnd->getCallInfo (&resolvedCallToken, pConstrainedToken , m_methodInfo->ftn , flags, &callInfo);
23522351 if (EmitCallIntrinsics (callInfo.hMethod , callInfo.sig ))
23532352 {
23542353 m_ip += 5 ;
23552354 return ;
23562355 }
2356+
2357+ if (callInfo.thisTransform != CORINFO_NO_THIS_TRANSFORM)
2358+ {
2359+ assert (pConstrainedToken != NULL );
2360+ StackInfo *pThisStackInfo = m_pStackPointer - callInfo.sig .numArgs - 1 ;
2361+ if (callInfo.thisTransform == CORINFO_BOX_THIS)
2362+ {
2363+ EmitBox (pThisStackInfo, pConstrainedToken->hClass , true );
2364+ }
2365+ else
2366+ {
2367+ assert (callInfo.thisTransform == CORINFO_DEREF_THIS);
2368+ AddIns (INTOP_LDIND_I);
2369+ m_pLastNewIns->SetSVar (pThisStackInfo->var );
2370+ m_pLastNewIns->data [0 ] = 0 ;
2371+ int32_t var = CreateVarExplicit (InterpTypeO, pConstrainedToken->hClass , INTERP_STACK_SLOT_SIZE);
2372+ new (pThisStackInfo) StackInfo (StackTypeO, pConstrainedToken->hClass , var);
2373+ m_pLastNewIns->SetDVar (pThisStackInfo->var );
2374+ }
2375+ }
23572376 }
23582377
23592378 if (newObj && (callInfo.classFlags & CORINFO_FLG_VAROBJSIZE))
@@ -2885,12 +2904,27 @@ void InterpCompiler::EmitLdLocA(int32_t var)
28852904 m_pLastNewIns->SetDVar (m_pStackPointer[-1 ].var );
28862905}
28872906
2907+ void InterpCompiler::EmitBox (StackInfo* pStackInfo, CORINFO_CLASS_HANDLE clsHnd, bool argByRef)
2908+ {
2909+ CORINFO_CLASS_HANDLE boxedClsHnd = m_compHnd->getTypeForBox (clsHnd);
2910+ CorInfoHelpFunc helpFunc = m_compHnd->getBoxHelper (clsHnd);
2911+ AddIns (argByRef ? INTOP_BOX_PTR : INTOP_BOX);
2912+ m_pLastNewIns->SetSVar (pStackInfo->var );
2913+
2914+ int32_t var = CreateVarExplicit (InterpTypeO, boxedClsHnd, INTERP_STACK_SLOT_SIZE);
2915+ new (pStackInfo) StackInfo (StackTypeO, boxedClsHnd, INTERP_STACK_SLOT_SIZE, var);
2916+
2917+ m_pLastNewIns->SetDVar (pStackInfo->var );
2918+ m_pLastNewIns->data [0 ] = GetDataItemIndex (clsHnd);
2919+ m_pLastNewIns->data [1 ] = GetDataItemIndexForHelperFtn (helpFunc);
2920+ }
2921+
28882922int InterpCompiler::GenerateCode (CORINFO_METHOD_INFO* methodInfo)
28892923{
28902924 bool readonly = false ;
28912925 bool tailcall = false ;
28922926 bool volatile_ = false ;
2893- CORINFO_RESOLVED_TOKEN* constrainedClass = NULL ;
2927+ CORINFO_RESOLVED_TOKEN* pConstrainedToken = NULL ;
28942928 CORINFO_RESOLVED_TOKEN constrainedToken;
28952929 uint8_t *codeEnd;
28962930 int numArgs = m_methodInfo->args .hasThis () + m_methodInfo->args .numArgs ;
@@ -4037,21 +4071,21 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
40374071 break ;
40384072 case CEE_CALLVIRT:
40394073 case CEE_CALL:
4040- EmitCall (constrainedClass , readonly, tailcall, false /* newObj*/ , false /* isCalli*/ );
4041- constrainedClass = NULL ;
4074+ EmitCall (pConstrainedToken , readonly, tailcall, false /* newObj*/ , false /* isCalli*/ );
4075+ pConstrainedToken = NULL ;
40424076 readonly = false ;
40434077 tailcall = false ;
40444078 break ;
40454079 case CEE_CALLI:
4046- EmitCall (NULL /* constrainedClass */ , false /* readonly*/ , false /* tailcall*/ , false /* newObj*/ , true /* isCalli*/ );
4047- constrainedClass = NULL ;
4080+ EmitCall (NULL /* pConstrainedToken */ , false /* readonly*/ , false /* tailcall*/ , false /* newObj*/ , true /* isCalli*/ );
4081+ pConstrainedToken = NULL ;
40484082 readonly = false ;
40494083 tailcall = false ;
40504084 break ;
40514085 case CEE_NEWOBJ:
40524086 {
4053- EmitCall (NULL /* constrainedClass */ , false /* readonly*/ , false /* tailcall*/ , true /* newObj*/ , false /* isCalli*/ );
4054- constrainedClass = NULL ;
4087+ EmitCall (NULL /* pConstrainedToken */ , false /* readonly*/ , false /* tailcall*/ , true /* newObj*/ , false /* isCalli*/ );
4088+ pConstrainedToken = NULL ;
40554089 readonly = false ;
40564090 tailcall = false ;
40574091 break ;
@@ -4428,12 +4462,9 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
44284462 {
44294463 uint32_t token = getU4LittleEndian (m_ip + 1 );
44304464
4431- constrainedToken.tokenScope = m_compScopeHnd;
4432- constrainedToken.tokenContext = METHOD_BEING_COMPILED_CONTEXT ();
4433- constrainedToken.token = token;
4434- constrainedToken.tokenType = CORINFO_TOKENKIND_Constrained;
4435- m_compHnd->resolveToken (&constrainedToken);
4436- constrainedClass = &constrainedToken;
4465+ ResolveToken (token, CORINFO_TOKENKIND_Constrained, &constrainedToken);
4466+
4467+ pConstrainedToken = &constrainedToken;
44374468 m_ip += 5 ;
44384469 break ;
44394470 }
@@ -4526,8 +4557,8 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
45264557 ResolveToken (token, CORINFO_TOKENKIND_Method, &resolvedToken);
45274558
45284559 CORINFO_CALL_INFO callInfo;
4529- m_compHnd->getCallInfo (&resolvedToken, constrainedClass , m_methodInfo->ftn , (CORINFO_CALLINFO_FLAGS)(CORINFO_CALLINFO_SECURITYCHECKS| CORINFO_CALLINFO_LDFTN), &callInfo);
4530- constrainedClass = NULL ;
4560+ m_compHnd->getCallInfo (&resolvedToken, pConstrainedToken , m_methodInfo->ftn , (CORINFO_CALLINFO_FLAGS)(CORINFO_CALLINFO_SECURITYCHECKS| CORINFO_CALLINFO_LDFTN), &callInfo);
4561+ pConstrainedToken = NULL ;
45314562
45324563 if (callInfo.kind == CORINFO_CALL)
45334564 {
@@ -4627,17 +4658,11 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
46274658
46284659 case CEE_BOX:
46294660 {
4661+ CORINFO_CLASS_HANDLE clsHnd = ResolveClassToken (getU4LittleEndian (m_ip + 1 ));
46304662 CHECK_STACK (1 );
46314663 m_pStackPointer -= 1 ;
4632- CORINFO_CLASS_HANDLE clsHnd = ResolveClassToken (getU4LittleEndian (m_ip + 1 ));
4633- CORINFO_CLASS_HANDLE boxedClsHnd = m_compHnd->getTypeForBox (clsHnd);
4634- CorInfoHelpFunc helpFunc = m_compHnd->getBoxHelper (clsHnd);
4635- AddIns (INTOP_BOX);
4636- m_pLastNewIns->SetSVar (m_pStackPointer[0 ].var );
4637- PushStackType (StackTypeO, boxedClsHnd);
4638- m_pLastNewIns->SetDVar (m_pStackPointer[-1 ].var );
4639- m_pLastNewIns->data [0 ] = GetDataItemIndex (clsHnd);
4640- m_pLastNewIns->data [1 ] = GetDataItemIndexForHelperFtn (helpFunc);
4664+ EmitBox (m_pStackPointer, clsHnd, false );
4665+ m_pStackPointer++;
46414666 m_ip += 5 ;
46424667 break ;
46434668 }
0 commit comments