@@ -581,11 +581,8 @@ bool InterpCompiler::CheckStackHelper(int n)
581581void InterpCompiler::PushTypeExplicit (StackType stackType, CORINFO_CLASS_HANDLE clsHnd, int size)
582582{
583583 EnsureStack (1 );
584- m_pStackPointer->type = stackType;
585- m_pStackPointer->clsHnd = clsHnd;
586- m_pStackPointer->size = ALIGN_UP_TO (size, INTERP_STACK_SLOT_SIZE);
587- int var = CreateVarExplicit (g_interpTypeFromStackType[stackType], clsHnd, size);
588- m_pStackPointer->var = var;
584+ int32_t var = CreateVarExplicit (g_interpTypeFromStackType[stackType], clsHnd, size);
585+ new (m_pStackPointer) StackInfo (stackType, clsHnd, var);
589586 m_pStackPointer++;
590587}
591588
@@ -1288,9 +1285,8 @@ void InterpCompiler::EmitConv(StackInfo *sp, StackType type, InterpOpcode convOp
12881285 InterpInst *newInst = AddIns (convOp);
12891286
12901287 newInst->SetSVar (sp->var );
1291- new (sp) StackInfo (type);
12921288 int32_t var = CreateVarExplicit (g_interpTypeFromStackType[type], NULL , INTERP_STACK_SLOT_SIZE);
1293- sp-> var = var;
1289+ new (sp) StackInfo (type, NULL , var) ;
12941290 newInst->SetDVar (var);
12951291
12961292 // NOTE: We rely on m_pLastNewIns == newInst upon return from this function. Make sure you preserve that if you change anything.
@@ -1708,10 +1704,7 @@ bool InterpCompiler::InitializeClauseBuildingBlocks(CORINFO_METHOD_INFO* methodI
17081704 // Initialize the filter stack state. It initially contains the exception object.
17091705 pFilterBB->stackHeight = 1 ;
17101706 pFilterBB->pStackState = (StackInfo*)AllocMemPool (sizeof (StackInfo));
1711- pFilterBB->pStackState [0 ].type = StackTypeO;
1712- pFilterBB->pStackState [0 ].size = INTERP_STACK_SLOT_SIZE;
1713- pFilterBB->pStackState [0 ].clsHnd = NULL ;
1714- pFilterBB->pStackState [0 ].var = pFilterBB->clauseVarIndex ;
1707+ new (pFilterBB->pStackState ) StackInfo (StackTypeO, NULL , pFilterBB->clauseVarIndex );
17151708
17161709 // Find and mark all basic blocks that are part of the filter region.
17171710 for (uint32_t j = clause.FilterOffset ; j < clause.HandlerOffset ; j++)
@@ -1740,10 +1733,7 @@ bool InterpCompiler::InitializeClauseBuildingBlocks(CORINFO_METHOD_INFO* methodI
17401733 // Initialize the catch / filtered handler stack state. It initially contains the exception object.
17411734 pCatchBB->stackHeight = 1 ;
17421735 pCatchBB->pStackState = (StackInfo*)AllocMemPool (sizeof (StackInfo));
1743- pCatchBB->pStackState [0 ].type = StackTypeO;
1744- pCatchBB->pStackState [0 ].size = INTERP_STACK_SLOT_SIZE;
1745- pCatchBB->pStackState [0 ].var = pCatchBB->clauseVarIndex ;
1746- pCatchBB->pStackState [0 ].clsHnd = NULL ;
1736+ new (pCatchBB->pStackState ) StackInfo (StackTypeO, NULL , pCatchBB->clauseVarIndex );
17471737 }
17481738 }
17491739
@@ -2315,7 +2305,7 @@ int InterpCompiler::EmitGenericHandleAsVar(const CORINFO_GENERICHANDLE_RESULT &e
23152305 return resultVar;
23162306}
23172307
2318- void InterpCompiler::EmitCall (CORINFO_RESOLVED_TOKEN* constrainedClass , bool readonly, bool tailcall, bool newObj, bool isCalli)
2308+ void InterpCompiler::EmitCall (CORINFO_RESOLVED_TOKEN* pConstrainedToken , bool readonly, bool tailcall, bool newObj, bool isCalli)
23192309{
23202310 uint32_t token = getU4LittleEndian (m_ip + 1 );
23212311 bool isVirtual = (*m_ip == CEE_CALLVIRT);
@@ -2345,19 +2335,38 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* constrainedClass, bool rea
23452335 }
23462336 else
23472337 {
2348-
23492338 ResolveToken (token, newObj ? CORINFO_TOKENKIND_NewObj : CORINFO_TOKENKIND_Method, &resolvedCallToken);
2350-
2339+
23512340 CORINFO_CALLINFO_FLAGS flags = (CORINFO_CALLINFO_FLAGS)(CORINFO_CALLINFO_ALLOWINSTPARAM | CORINFO_CALLINFO_SECURITYCHECKS | CORINFO_CALLINFO_DISALLOW_STUB);
23522341 if (isVirtual)
23532342 flags = (CORINFO_CALLINFO_FLAGS)(flags | CORINFO_CALLINFO_CALLVIRT);
23542343
2355- m_compHnd->getCallInfo (&resolvedCallToken, constrainedClass , m_methodInfo->ftn , flags, &callInfo);
2344+ m_compHnd->getCallInfo (&resolvedCallToken, pConstrainedToken , m_methodInfo->ftn , flags, &callInfo);
23562345 if (EmitCallIntrinsics (callInfo.hMethod , callInfo.sig ))
23572346 {
23582347 m_ip += 5 ;
23592348 return ;
23602349 }
2350+
2351+ if (callInfo.thisTransform != CORINFO_NO_THIS_TRANSFORM)
2352+ {
2353+ assert (pConstrainedToken != NULL );
2354+ StackInfo *pThisStackInfo = m_pStackPointer - callInfo.sig .numArgs - 1 ;
2355+ if (callInfo.thisTransform == CORINFO_BOX_THIS)
2356+ {
2357+ EmitBox (pThisStackInfo, pConstrainedToken->hClass , true );
2358+ }
2359+ else
2360+ {
2361+ assert (callInfo.thisTransform == CORINFO_DEREF_THIS);
2362+ AddIns (INTOP_LDIND_I);
2363+ m_pLastNewIns->SetSVar (pThisStackInfo->var );
2364+ m_pLastNewIns->data [0 ] = 0 ;
2365+ int32_t var = CreateVarExplicit (InterpTypeO, pConstrainedToken->hClass , INTERP_STACK_SLOT_SIZE);
2366+ new (pThisStackInfo) StackInfo (StackTypeO, pConstrainedToken->hClass , var);
2367+ m_pLastNewIns->SetDVar (pThisStackInfo->var );
2368+ }
2369+ }
23612370 }
23622371
23632372 if (newObj && (callInfo.classFlags & CORINFO_FLG_VAROBJSIZE))
@@ -2889,12 +2898,27 @@ void InterpCompiler::EmitLdLocA(int32_t var)
28892898 m_pLastNewIns->SetDVar (m_pStackPointer[-1 ].var );
28902899}
28912900
2901+ void InterpCompiler::EmitBox (StackInfo* pStackInfo, CORINFO_CLASS_HANDLE clsHnd, bool argByRef)
2902+ {
2903+ CORINFO_CLASS_HANDLE boxedClsHnd = m_compHnd->getTypeForBox (clsHnd);
2904+ CorInfoHelpFunc helpFunc = m_compHnd->getBoxHelper (clsHnd);
2905+ AddIns (argByRef ? INTOP_BOX_PTR : INTOP_BOX);
2906+ m_pLastNewIns->SetSVar (pStackInfo->var );
2907+
2908+ int32_t var = CreateVarExplicit (InterpTypeO, boxedClsHnd, INTERP_STACK_SLOT_SIZE);
2909+ new (pStackInfo) StackInfo (StackTypeO, boxedClsHnd, var);
2910+
2911+ m_pLastNewIns->SetDVar (pStackInfo->var );
2912+ m_pLastNewIns->data [0 ] = GetDataItemIndex (clsHnd);
2913+ m_pLastNewIns->data [1 ] = GetDataItemIndexForHelperFtn (helpFunc);
2914+ }
2915+
28922916int InterpCompiler::GenerateCode (CORINFO_METHOD_INFO* methodInfo)
28932917{
28942918 bool readonly = false ;
28952919 bool tailcall = false ;
28962920 bool volatile_ = false ;
2897- CORINFO_RESOLVED_TOKEN* constrainedClass = NULL ;
2921+ CORINFO_RESOLVED_TOKEN* pConstrainedToken = NULL ;
28982922 CORINFO_RESOLVED_TOKEN constrainedToken;
28992923 uint8_t *codeEnd;
29002924 int numArgs = m_methodInfo->args .hasThis () + m_methodInfo->args .numArgs ;
@@ -4057,21 +4081,21 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
40574081 break ;
40584082 case CEE_CALLVIRT:
40594083 case CEE_CALL:
4060- EmitCall (constrainedClass , readonly, tailcall, false /* newObj*/ , false /* isCalli*/ );
4061- constrainedClass = NULL ;
4084+ EmitCall (pConstrainedToken , readonly, tailcall, false /* newObj*/ , false /* isCalli*/ );
4085+ pConstrainedToken = NULL ;
40624086 readonly = false ;
40634087 tailcall = false ;
40644088 break ;
40654089 case CEE_CALLI:
4066- EmitCall (NULL /* constrainedClass */ , false /* readonly*/ , false /* tailcall*/ , false /* newObj*/ , true /* isCalli*/ );
4067- constrainedClass = NULL ;
4090+ EmitCall (NULL /* pConstrainedToken */ , false /* readonly*/ , false /* tailcall*/ , false /* newObj*/ , true /* isCalli*/ );
4091+ pConstrainedToken = NULL ;
40684092 readonly = false ;
40694093 tailcall = false ;
40704094 break ;
40714095 case CEE_NEWOBJ:
40724096 {
4073- EmitCall (NULL /* constrainedClass */ , false /* readonly*/ , false /* tailcall*/ , true /* newObj*/ , false /* isCalli*/ );
4074- constrainedClass = NULL ;
4097+ EmitCall (NULL /* pConstrainedToken */ , false /* readonly*/ , false /* tailcall*/ , true /* newObj*/ , false /* isCalli*/ );
4098+ pConstrainedToken = NULL ;
40754099 readonly = false ;
40764100 tailcall = false ;
40774101 break ;
@@ -4448,12 +4472,9 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
44484472 {
44494473 uint32_t token = getU4LittleEndian (m_ip + 1 );
44504474
4451- constrainedToken.tokenScope = m_compScopeHnd;
4452- constrainedToken.tokenContext = METHOD_BEING_COMPILED_CONTEXT ();
4453- constrainedToken.token = token;
4454- constrainedToken.tokenType = CORINFO_TOKENKIND_Constrained;
4455- m_compHnd->resolveToken (&constrainedToken);
4456- constrainedClass = &constrainedToken;
4475+ ResolveToken (token, CORINFO_TOKENKIND_Constrained, &constrainedToken);
4476+
4477+ pConstrainedToken = &constrainedToken;
44574478 m_ip += 5 ;
44584479 break ;
44594480 }
@@ -4546,8 +4567,8 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
45464567 ResolveToken (token, CORINFO_TOKENKIND_Method, &resolvedToken);
45474568
45484569 CORINFO_CALL_INFO callInfo;
4549- m_compHnd->getCallInfo (&resolvedToken, constrainedClass , m_methodInfo->ftn , (CORINFO_CALLINFO_FLAGS)(CORINFO_CALLINFO_SECURITYCHECKS| CORINFO_CALLINFO_LDFTN), &callInfo);
4550- constrainedClass = NULL ;
4570+ m_compHnd->getCallInfo (&resolvedToken, pConstrainedToken , m_methodInfo->ftn , (CORINFO_CALLINFO_FLAGS)(CORINFO_CALLINFO_SECURITYCHECKS| CORINFO_CALLINFO_LDFTN), &callInfo);
4571+ pConstrainedToken = NULL ;
45514572
45524573 if (callInfo.kind == CORINFO_CALL)
45534574 {
@@ -4650,17 +4671,11 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
46504671
46514672 case CEE_BOX:
46524673 {
4674+ CORINFO_CLASS_HANDLE clsHnd = ResolveClassToken (getU4LittleEndian (m_ip + 1 ));
46534675 CHECK_STACK (1 );
46544676 m_pStackPointer -= 1 ;
4655- CORINFO_CLASS_HANDLE clsHnd = ResolveClassToken (getU4LittleEndian (m_ip + 1 ));
4656- CORINFO_CLASS_HANDLE boxedClsHnd = m_compHnd->getTypeForBox (clsHnd);
4657- CorInfoHelpFunc helpFunc = m_compHnd->getBoxHelper (clsHnd);
4658- AddIns (INTOP_BOX);
4659- m_pLastNewIns->SetSVar (m_pStackPointer[0 ].var );
4660- PushStackType (StackTypeO, boxedClsHnd);
4661- m_pLastNewIns->SetDVar (m_pStackPointer[-1 ].var );
4662- m_pLastNewIns->data [0 ] = GetDataItemIndex (clsHnd);
4663- m_pLastNewIns->data [1 ] = GetDataItemIndexForHelperFtn (helpFunc);
4677+ EmitBox (m_pStackPointer, clsHnd, false );
4678+ m_pStackPointer++;
46644679 m_ip += 5 ;
46654680 break ;
46664681 }
0 commit comments