@@ -3007,36 +3007,53 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
3007
3007
m_compHnd->getMethodSig (ctorMethod, &ctorSignature);
3008
3008
ctorClass = m_compHnd->getMethodClass (ctorMethod);
3009
3009
int32_t numArgs = ctorSignature.numArgs ;
3010
+ bool isStringOrArray = m_compHnd->getClassAttribs (ctorClass) & CORINFO_FLG_VAROBJSIZE;
3011
+ int32_t numExtraArgs = isStringOrArray ? 1 : 2 ;
3012
+ int32_t callArgOffset = isStringOrArray ? 0 : 1 ;
3010
3013
3011
- // TODO Special case array ctor / string ctor
3012
3014
m_pStackPointer -= numArgs;
3013
3015
3014
3016
// Allocate callArgs for the call, this + numArgs + terminator
3015
- int32_t *callArgs = (int32_t *) AllocMemPool ((numArgs + 2 ) * sizeof (int32_t ));
3017
+ int32_t *callArgs = (int32_t *) AllocMemPool ((numArgs + numExtraArgs ) * sizeof (int32_t ));
3016
3018
for (int i = 0 ; i < numArgs; i++)
3017
- callArgs[i + 1 ] = m_pStackPointer[i].var ;
3018
- callArgs[numArgs + 1 ] = -1 ;
3019
+ callArgs[i + callArgOffset ] = m_pStackPointer[i].var ;
3020
+ callArgs[numArgs + callArgOffset ] = -1 ;
3019
3021
3020
3022
// Push the return value and `this` argument to the ctor
3021
3023
InterpType retType = GetInterpType (m_compHnd->asCorInfoType (ctorClass));
3022
- int32_t vtsize = 0 ;
3023
- if (retType == InterpTypeVT)
3024
+ int32_t vtsize = 0 , dVar, thisVar;
3025
+ if (isStringOrArray)
3026
+ {
3027
+ // result
3028
+ PushInterpType (retType, ctorClass);
3029
+ dVar = m_pStackPointer[-1 ].var ;
3030
+ thisVar = -1 ;
3031
+ }
3032
+ else if (retType == InterpTypeVT)
3024
3033
{
3025
3034
vtsize = m_compHnd->getClassSize (ctorClass);
3026
3035
PushTypeVT (ctorClass, vtsize);
3027
3036
PushInterpType (InterpTypeByRef, NULL );
3037
+ dVar = m_pStackPointer[-2 ].var ;
3038
+ thisVar = m_pStackPointer[-1 ].var ;
3028
3039
}
3029
3040
else
3030
3041
{
3042
+ // result
3031
3043
PushInterpType (retType, ctorClass);
3044
+ // this-ref
3032
3045
PushInterpType (retType, ctorClass);
3046
+ dVar = m_pStackPointer[-2 ].var ;
3047
+ thisVar = m_pStackPointer[-1 ].var ;
3048
+ }
3049
+
3050
+ if (!isStringOrArray)
3051
+ {
3052
+ // Consider this arg as being defined, although newobj defines it
3053
+ AddIns (INTOP_DEF);
3054
+ m_pLastNewIns->SetDVar (thisVar);
3055
+ callArgs[0 ] = thisVar;
3033
3056
}
3034
- int32_t dVar = m_pStackPointer[-2 ].var ;
3035
- int32_t thisVar = m_pStackPointer[-1 ].var ;
3036
- // Consider this arg as being defined, although newobj defines it
3037
- AddIns (INTOP_DEF);
3038
- m_pLastNewIns->SetDVar (thisVar);
3039
- callArgs[0 ] = thisVar;
3040
3057
3041
3058
if (retType == InterpTypeVT)
3042
3059
{
@@ -3048,6 +3065,7 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
3048
3065
AddIns (INTOP_NEWOBJ);
3049
3066
m_pLastNewIns->data [1 ] = GetDataItemIndex (ctorClass);
3050
3067
}
3068
+
3051
3069
m_pLastNewIns->data [0 ] = GetMethodDataItemIndex (ctorMethod);
3052
3070
m_pLastNewIns->SetSVar (CALL_ARGS_SVAR);
3053
3071
m_pLastNewIns->SetDVar (dVar);
@@ -3057,7 +3075,8 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
3057
3075
m_pLastNewIns->info .pCallInfo ->pCallArgs = callArgs;
3058
3076
3059
3077
// Pop this, the result of the newobj still remains on the stack
3060
- m_pStackPointer--;
3078
+ if (!isStringOrArray)
3079
+ m_pStackPointer--;
3061
3080
break ;
3062
3081
}
3063
3082
case CEE_DUP:
0 commit comments