@@ -1645,6 +1645,11 @@ static void FreeInterpreterStackMap(void *key, void *value, void *userdata)
16451645 delete (InterpreterStackMap *)value;
16461646}
16471647
1648+ static void InterpreterCompilerBreak ()
1649+ {
1650+ assert (!" InterpreterCompilerBreak reached" );
1651+ }
1652+
16481653InterpCompiler::InterpCompiler (COMP_HANDLE compHnd,
16491654 CORINFO_METHOD_INFO* methodInfo)
16501655 : m_stackmapsByClass(FreeInterpreterStackMap)
@@ -1689,6 +1694,13 @@ InterpMethod* InterpCompiler::CompileMethod()
16891694 printf (" Interpreter compile method %s\n " , m_methodName.GetUnderlyingArray ());
16901695 }
16911696#endif
1697+ #ifdef DEBUG
1698+ if (InterpConfig.InterpBreak ().contains (m_compHnd, m_methodInfo->ftn , m_classHnd, &m_methodInfo->args ))
1699+ {
1700+ InterpreterCompilerBreak ();
1701+ }
1702+ #endif
1703+
16921704 m_isSynchronized = m_compHnd->getMethodAttribs (m_methodHnd) & CORINFO_FLG_SYNCH;
16931705 if (m_isSynchronized)
16941706 {
@@ -3679,6 +3691,90 @@ void InterpCompiler::EmitCalli(bool isTailCall, void* calliCookie, int callIFunc
36793691 m_pLastNewIns->SetSVars2 (CALL_ARGS_SVAR, callIFunctionPointerVar);
36803692}
36813693
3694+ void InterpCompiler::EmitCanAccessCallout (CORINFO_RESOLVED_TOKEN *pResolvedToken)
3695+ {
3696+ CORINFO_HELPER_DESC calloutHelper;
3697+ CorInfoIsAccessAllowedResult accessAllowed =
3698+ m_compHnd->canAccessClass (pResolvedToken, m_methodHnd, &calloutHelper);
3699+
3700+ // Inject call to callsite callout helper
3701+ EmitCallsiteCallout (accessAllowed, &calloutHelper);
3702+ }
3703+
3704+ void InterpCompiler::EmitCallsiteCallout (CorInfoIsAccessAllowedResult accessAllowed, CORINFO_HELPER_DESC* calloutDesc)
3705+ {
3706+ if (accessAllowed == CORINFO_ACCESS_ILLEGAL)
3707+ {
3708+ int32_t svars[CORINFO_ACCESS_ALLOWED_MAX_ARGS];
3709+
3710+ for (unsigned i = 0 ; i < calloutDesc->numArgs ; i++)
3711+ {
3712+ void *value = NULL ;
3713+ void *pValue = NULL ;
3714+
3715+ switch (calloutDesc->args [i].argType )
3716+ {
3717+ case CORINFO_HELPER_ARG_TYPE_Class:
3718+ value = (void *)m_compHnd->embedClassHandle (calloutDesc->args [i].classHandle , &pValue);
3719+ break ;
3720+ case CORINFO_HELPER_ARG_TYPE_Method:
3721+ value = (void *)m_compHnd->embedMethodHandle (calloutDesc->args [i].methodHandle , &pValue);
3722+ break ;
3723+ default :
3724+ NO_WAY (" Callsite callout with unsupported arg type" );
3725+ }
3726+
3727+ if (value == NULL )
3728+ {
3729+ if (pValue == NULL )
3730+ {
3731+ NO_WAY (" Callsite callout with unsupported arg type" );
3732+ }
3733+
3734+ AddIns (INTOP_LDPTR);
3735+ m_pLastNewIns->data [0 ] = GetDataItemIndex (pValue);
3736+ PushInterpType (InterpTypeI, nullptr );
3737+ int tempVar = m_pStackPointer[-1 ].var ;
3738+ m_pLastNewIns->SetDVar (tempVar);
3739+
3740+ // Now we generate an LDIND_I to get the actual value out of the ref
3741+ AddIns (INTOP_LDIND_I);
3742+ m_pLastNewIns->data [0 ] = 0 ;
3743+ m_pLastNewIns->SetSVar (tempVar);
3744+ m_pStackPointer--;
3745+ PushInterpType (InterpTypeI, NULL );
3746+ m_pLastNewIns->SetDVar (m_pStackPointer[-1 ].var );
3747+ m_pStackPointer--;
3748+ svars[i] = m_pStackPointer[0 ].var ;
3749+ }
3750+ else
3751+ {
3752+ AddIns (INTOP_LDPTR);
3753+ m_pLastNewIns->data [0 ] = GetDataItemIndex (value);
3754+ PushInterpType (InterpTypeI, nullptr );
3755+ svars[i] = m_pStackPointer[-1 ].var ;
3756+ m_pLastNewIns->SetDVar (svars[i]);
3757+ m_pStackPointer--;
3758+ }
3759+ }
3760+ if (calloutDesc->numArgs == 2 )
3761+ {
3762+ AddIns (INTOP_CALL_HELPER_V_SS);
3763+ m_pLastNewIns->SetSVars2 (svars[0 ], svars[1 ]);
3764+ }
3765+ else if (calloutDesc->numArgs == 3 )
3766+ {
3767+ AddIns (INTOP_CALL_HELPER_V_SSS);
3768+ m_pLastNewIns->SetSVars3 (svars[0 ], svars[1 ], svars[2 ]);
3769+ }
3770+ else
3771+ {
3772+ NO_WAY (" Callsite callout with unsupported number of args" );
3773+ }
3774+ m_pLastNewIns->data [0 ] = GetDataForHelperFtn (calloutDesc->helperNum );
3775+ }
3776+ }
3777+
36823778void InterpCompiler::EmitCall (CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool readonly, bool tailcall, bool newObj, bool isCalli)
36833779{
36843780 uint32_t token = getU4LittleEndian (m_ip + 1 );
@@ -3761,6 +3857,10 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
37613857 flags = (CORINFO_CALLINFO_FLAGS)(flags | CORINFO_CALLINFO_CALLVIRT);
37623858
37633859 m_compHnd->getCallInfo (&resolvedCallToken, pConstrainedToken, m_methodInfo->ftn , flags, &callInfo);
3860+
3861+ // Inject call to callsite callout helper
3862+ EmitCallsiteCallout (callInfo.accessAllowed , &callInfo.callsiteCalloutHelper );
3863+
37643864 if (callInfo.methodFlags & CORINFO_FLG_INTRINSIC)
37653865 {
37663866 NamedIntrinsic ni = GetNamedIntrinsic (m_compHnd, m_methodHnd, callInfo.hMethod );
@@ -6293,6 +6393,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
62936393 ResolveToken (token, CORINFO_TOKENKIND_Field, &resolvedToken);
62946394 m_compHnd->getFieldInfo (&resolvedToken, m_methodHnd, CORINFO_ACCESS_ADDRESS, &fieldInfo);
62956395
6396+ // Inject call to callsite callout helper
6397+ EmitCallsiteCallout (fieldInfo.accessAllowed , &fieldInfo.accessCalloutHelper );
6398+
62966399 bool isStatic = !!(fieldInfo.fieldFlags & CORINFO_FLG_FIELD_STATIC);
62976400
62986401 if (isStatic)
@@ -6324,6 +6427,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
63246427 ResolveToken (token, CORINFO_TOKENKIND_Field, &resolvedToken);
63256428 m_compHnd->getFieldInfo (&resolvedToken, m_methodHnd, CORINFO_ACCESS_GET, &fieldInfo);
63266429
6430+ // Inject call to callsite callout helper
6431+ EmitCallsiteCallout (fieldInfo.accessAllowed , &fieldInfo.accessCalloutHelper );
6432+
63276433 CorInfoType fieldType = fieldInfo.fieldType ;
63286434 bool isStatic = !!(fieldInfo.fieldFlags & CORINFO_FLG_FIELD_STATIC);
63296435 InterpType interpFieldType = GetInterpType (fieldType);
@@ -6384,6 +6490,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
63846490 ResolveToken (token, CORINFO_TOKENKIND_Field, &resolvedToken);
63856491 m_compHnd->getFieldInfo (&resolvedToken, m_methodHnd, CORINFO_ACCESS_GET, &fieldInfo);
63866492
6493+ // Inject call to callsite callout helper
6494+ EmitCallsiteCallout (fieldInfo.accessAllowed , &fieldInfo.accessCalloutHelper );
6495+
63876496 CorInfoType fieldType = fieldInfo.fieldType ;
63886497 bool isStatic = !!(fieldInfo.fieldFlags & CORINFO_FLG_FIELD_STATIC);
63896498 InterpType interpFieldType = GetInterpType (fieldType);
@@ -6418,6 +6527,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
64186527 ResolveToken (token, CORINFO_TOKENKIND_Field, &resolvedToken);
64196528 m_compHnd->getFieldInfo (&resolvedToken, m_methodHnd, CORINFO_ACCESS_ADDRESS, &fieldInfo);
64206529
6530+ // Inject call to callsite callout helper
6531+ EmitCallsiteCallout (fieldInfo.accessAllowed , &fieldInfo.accessCalloutHelper );
6532+
64216533 EmitStaticFieldAddress (&fieldInfo, &resolvedToken);
64226534
64236535 m_ip += 5 ;
@@ -6431,6 +6543,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
64316543 ResolveToken (token, CORINFO_TOKENKIND_Field, &resolvedToken);
64326544 m_compHnd->getFieldInfo (&resolvedToken, m_methodHnd, CORINFO_ACCESS_GET, &fieldInfo);
64336545
6546+ // Inject call to callsite callout helper
6547+ EmitCallsiteCallout (fieldInfo.accessAllowed , &fieldInfo.accessCalloutHelper );
6548+
64346549 CorInfoType fieldType = fieldInfo.fieldType ;
64356550 InterpType interpFieldType = GetInterpType (fieldType);
64366551
@@ -6454,6 +6569,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
64546569 ResolveToken (token, CORINFO_TOKENKIND_Field, &resolvedToken);
64556570 m_compHnd->getFieldInfo (&resolvedToken, m_methodHnd, CORINFO_ACCESS_GET, &fieldInfo);
64566571
6572+ // Inject call to callsite callout helper
6573+ EmitCallsiteCallout (fieldInfo.accessAllowed , &fieldInfo.accessCalloutHelper );
6574+
64576575 CorInfoType fieldType = fieldInfo.fieldType ;
64586576 InterpType interpFieldType = GetInterpType (fieldType);
64596577
@@ -6584,6 +6702,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
65846702
65856703 CORINFO_RESOLVED_TOKEN resolvedToken;
65866704 ResolveToken (token, CORINFO_TOKENKIND_Class, &resolvedToken);
6705+
6706+ EmitCanAccessCallout (&resolvedToken);
6707+
65876708 CORINFO_GENERICHANDLE_RESULT embedInfo;
65886709 m_compHnd->embedGenericHandle (&resolvedToken, true , m_methodInfo->ftn , &embedInfo);
65896710 assert (embedInfo.compileTimeHandle != NULL );
@@ -6834,6 +6955,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
68346955 NO_WAY (" Currently do not support LDFTN of Parameterized functions" );
68356956 }
68366957
6958+ // Inject call to callsite callout helper
6959+ EmitCallsiteCallout (callInfo.accessAllowed , &callInfo.callsiteCalloutHelper );
6960+
68376961 m_pStackPointer--;
68386962 int thisVar = m_pStackPointer[0 ].var ;
68396963
@@ -6864,6 +6988,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
68646988 NO_WAY (" Currently do not support LDFTN of Parameterized functions" );
68656989 }
68666990
6991+ // Inject call to callsite callout helper
6992+ EmitCallsiteCallout (callInfo.accessAllowed , &callInfo.callsiteCalloutHelper );
6993+
68676994DO_LDFTN:
68686995 if (callInfo.kind == CORINFO_CALL)
68696996 {
@@ -6961,6 +7088,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
69617088 CHECK_STACK (1 );
69627089 CORINFO_RESOLVED_TOKEN resolvedToken;
69637090 ResolveToken (token, CORINFO_TOKENKIND_Box, &resolvedToken);
7091+
7092+ EmitCanAccessCallout (&resolvedToken);
7093+
69647094 if (m_compHnd->isValueClass (resolvedToken.hClass ))
69657095 {
69667096 CORINFO_GENERICHANDLE_RESULT embedInfo;
@@ -6980,6 +7110,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
69807110 CHECK_STACK (1 );
69817111 CORINFO_RESOLVED_TOKEN resolvedToken;
69827112 ResolveToken (token, CORINFO_TOKENKIND_Class, &resolvedToken);
7113+
7114+ EmitCanAccessCallout (&resolvedToken);
7115+
69837116 CORINFO_GENERICHANDLE_RESULT embedInfo;
69847117 m_compHnd->embedGenericHandle (&resolvedToken, false , m_methodInfo->ftn , &embedInfo);
69857118 DeclarePointerIsClass ((CORINFO_CLASS_HANDLE)embedInfo.compileTimeHandle );
@@ -7067,6 +7200,8 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
70677200 CORINFO_RESOLVED_TOKEN resolvedToken;
70687201 ResolveToken (token, CORINFO_TOKENKIND_Newarr, &resolvedToken);
70697202
7203+ EmitCanAccessCallout (&resolvedToken);
7204+
70707205 CORINFO_CLASS_HANDLE arrayClsHnd = resolvedToken.hClass ;
70717206 CorInfoHelpFunc helpFunc = m_compHnd->getNewArrHelper (arrayClsHnd);
70727207 DeclarePointerIsClass (arrayClsHnd);
@@ -7465,6 +7600,8 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
74657600 CORINFO_RESOLVED_TOKEN resolvedToken;
74667601 ResolveToken (getU4LittleEndian (m_ip + 1 ), CORINFO_TOKENKIND_Casting, &resolvedToken);
74677602
7603+ EmitCanAccessCallout (&resolvedToken);
7604+
74687605 CorInfoHelpFunc castingHelper = m_compHnd->getCastingHelper (&resolvedToken, *m_ip == CEE_CASTCLASS /* throwing */ );
74697606
74707607 CORINFO_GENERICHANDLE_RESULT embedInfo;
0 commit comments