-
Notifications
You must be signed in to change notification settings - Fork 5k
Add support for string constructors to the interpreter #115914
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for string constructors in the interpreter and updates the associated call stub generation.
- Added a new test case (TestStringCtor) to verify string constructor functionality
- Updated interpreter execution logic to correctly handle fcalls for string constructors
- Adjusted call stub generation to account for special string constructors
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
src/tests/JIT/interpreter/Interpreter.cs | Added test method for string constructor support |
src/coreclr/vm/interpexec.cpp | Updated interpreter method call to support special string constructors |
src/coreclr/vm/callstubgenerator.cpp | Modified call stub generation for special constructor handling |
@@ -1186,15 +1186,46 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr | |||
callArgsOffset = ip[2]; | |||
methodSlot = ip[3]; | |||
|
|||
OBJECTREF objRef = AllocateObject((MethodTable*)pMethod->pDataItems[ip[4]]); | |||
MethodTable *pClass = (MethodTable*)pMethod->pDataItems[ip[4]]; | |||
// FIXME: Duplicated code from CALL_INTERP_SLOT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider refactoring the duplicated code block for handling string constructor invocations to improve maintainability.
// FIXME: Duplicated code from CALL_INTERP_SLOT |
Copilot uses AI. Check for mistakes.
Tagging subscribers to this area: @dotnet/interop-contrib |
Co-authored-by: Aaron Robinson <[email protected]>
Anyone know what's up with this crossdac failure on CI?
EDIT: Looks like https://developercommunity.visualstudio.com/t/C1090-PDB-API-call-failed-error-code-2/48897 |
Also tracked here: #48070 . Build analysis should flag it for you. |
// fcall that is basically a static method that returns the new instance. | ||
if (pMD && pClass->HasComponentSize()) | ||
{ | ||
// The compiler didn't know about this so it reserved space for a this-reference. We need to skip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds like a temporary workaround. The compiler can know about this (by checking CORINFO_FLG_VAROBJSIZE
flag). What needs to happen to move this logic to the compiler?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_compHnd didn't appear to expose the things I needed to determine this. I can take another look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the flag CORINFO_FLG_VAROBJSIZE
that @jkotas mentioned offline yesterday:
runtime/src/coreclr/jit/importercalls.cpp
Lines 1010 to 1026 in fc85a87
if (opcode == CEE_NEWOBJ) | |
{ | |
if (clsFlags & CORINFO_FLG_VAROBJSIZE) | |
{ | |
assert(!(clsFlags & CORINFO_FLG_ARRAY)); // arrays handled separately | |
// This is a 'new' of a variable sized object, wher | |
// the constructor is to return the object. In this case | |
// the constructor claims to return VOID but we know it | |
// actually returns the new object | |
assert(callRetTyp == TYP_VOID); | |
callRetTyp = TYP_REF; | |
call->gtType = TYP_REF; | |
impSpillSpecialSideEff(); | |
impPushOnStack(call, typeInfo(clsHnd)); | |
} | |
else |
You can get it by
getClassAttribs
or by the getCallInfo
in the CORINFO_CALL_INFO::classFlags
.
@@ -547,7 +547,14 @@ CallStubHeader *CallStubGenerator::GenerateCallStub(MethodDesc *pMD, AllocMemTra | |||
|
|||
_ASSERTE(pMD != NULL); | |||
|
|||
// Classes like System.String have special constructors that are fcalls. When invoking these, we need to override | |||
// HasThis (there's no thisref) and the return type (the return value is the new instance, not void). | |||
bool isSpecialConstructor = pMD->IsCtor() && pMD->GetMethodTable()->HasComponentSize(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The runtime uses a bit different condition to decide whether to clear the HasThis, it would be good to use the same one:
runtime/src/coreclr/vm/frames.cpp
Line 1518 in 87b35f4
bool fCtorOfVariableSizedObject = msig.HasThis() && (pFunction->GetMethodTable() == g_pStringClass) && pFunction->IsCtor(); |
No description provided.