@@ -567,8 +567,43 @@ void InterpCompiler::EmitBBEndVarMoves(InterpBasicBlock *pTargetBB)
567567 int dVar = pTargetBB->pStackState [i].var ;
568568 if (sVar != dVar)
569569 {
570- InterpType interpType = m_pVars[sVar ].interpType ;
571- int32_t movOp = InterpGetMovForType (interpType, false );
570+ InterpType interpType = g_interpTypeFromStackType[m_pStackBase[i].GetStackType ()];
571+ InterpType interpDestType = g_interpTypeFromStackType[pTargetBB->pStackState [i].GetStackType ()];
572+ int32_t movOp;
573+ if (interpType != interpDestType)
574+ {
575+ if (interpType == InterpTypeR4 && interpDestType == InterpTypeR8)
576+ {
577+ movOp = INTOP_CONV_R8_R4;
578+ }
579+ else if (interpType == InterpTypeR8 && interpDestType == InterpTypeR4)
580+ {
581+ movOp = INTOP_CONV_R4_R8;
582+ }
583+ else if (interpType == InterpTypeI && interpDestType == InterpTypeByRef)
584+ {
585+ movOp = InterpGetMovForType (interpDestType, false );
586+ }
587+ #ifdef TARGET_64BIT
588+ // nint and int32 can be used interchangeably. Add implicit conversions.
589+ else if (interpType == InterpTypeI4 && interpDestType == InterpTypeI8)
590+ {
591+ movOp = INTOP_CONV_I8_I4;
592+ }
593+ else if (interpType == InterpTypeI8 && interpDestType == InterpTypeI4)
594+ {
595+ movOp = InterpGetMovForType (interpDestType, false );
596+ }
597+ #endif // TARGET_64BIT
598+ else
599+ {
600+ BADCODE (" Incompatible types on stack between basic blocks" );
601+ }
602+ }
603+ else
604+ {
605+ movOp = InterpGetMovForType (interpType, false );
606+ }
572607
573608 AddIns (movOp);
574609 m_pLastNewIns->SetSVar (sVar );
@@ -7989,6 +8024,26 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
79898024
79908025 if (m_compHnd->isValueClass (resolvedToken.hClass ))
79918026 {
8027+ CorInfoType asCorInfoType = m_compHnd->asCorInfoType (m_compHnd->getTypeForBox (resolvedToken.hClass ));
8028+ if (asCorInfoType == CORINFO_TYPE_FLOAT && m_pStackPointer[-1 ].GetStackType () == StackTypeR8)
8029+ {
8030+ EmitConv (m_pStackPointer - 1 , StackTypeR4, INTOP_CONV_R4_R8);
8031+ }
8032+ else if (asCorInfoType == CORINFO_TYPE_DOUBLE && m_pStackPointer[-1 ].GetStackType () == StackTypeR4)
8033+ {
8034+ EmitConv (m_pStackPointer - 1 , StackTypeR8, INTOP_CONV_R8_R4);
8035+ }
8036+ #ifdef TARGET_64BIT
8037+ // nint and int32 can be used interchangeably. Add implicit conversions.
8038+ else if (asCorInfoType == CORINFO_TYPE_NATIVEINT && m_pStackPointer[-1 ].GetStackType () == StackTypeI4)
8039+ {
8040+ EmitConv (m_pStackPointer - 1 , StackTypeI8, INTOP_CONV_I8_I4);
8041+ }
8042+ else if (asCorInfoType == CORINFO_TYPE_NATIVEUINT && m_pStackPointer[-1 ].GetStackType () == StackTypeI4)
8043+ {
8044+ EmitConv (m_pStackPointer - 1 , StackTypeI8, INTOP_CONV_I8_U4);
8045+ }
8046+ #endif // TARGET_64BIT
79928047 CORINFO_GENERICHANDLE_RESULT embedInfo;
79938048 m_compHnd->embedGenericHandle (&resolvedToken, false , m_methodInfo->ftn , &embedInfo);
79948049 m_pStackPointer -= 1 ;
0 commit comments