Skip to content

Conversation

@janvorli
Copy link
Member

@janvorli janvorli commented Nov 3, 2025

This change adds a way to wrap any method call in a SEH exception try / catch. Until now, we were adding a new function for each case that needed this wrapping.

I've verified that the generated code in the release build is the same as before this change.

This change adds a templated way to wrap any method call in a SEH
exception try / catch. Until now, we were adding a new function for each
case that needed this wrapping.
@janvorli janvorli added this to the 11.0.0 milestone Nov 3, 2025
@janvorli janvorli self-assigned this Nov 3, 2025
@janvorli janvorli requested a review from BrzVlad as a code owner November 3, 2025 18:43
Copilot AI review requested due to automatic review settings November 3, 2025 18:43
@janvorli janvorli requested a review from kg as a code owner November 3, 2025 18:43
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @BrzVlad, @janvorli, @kg
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a 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 refactors exception handling for method calls in the interpreter by introducing a generic CallWithSEHWrapper template function to replace specialized wrapper functions (CallPreStub and CallGetMethodDescOfVirtualizedCode). This consolidates duplicate SEH exception handling logic into a single reusable template.

  • Replaced two specialized SEH wrapper functions with a single generic template
  • Updated all call sites to use the new generic wrapper
  • Consolidated duplicate exception handling logic

}

template<typename Obj, typename Method, typename... Args>
auto CallWithSEHWrapper(Obj* obj, Method method, Args... args) -> decltype((obj->*method)(args...))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we instead use a no-parameter lambda here (and capture the args into the state object)? Would avoid pulling in tuple and that machinery.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why would you prefer to avoid using the tuple?
Anyways, I've changed the implementation to use the lambda as you've suggested. The benefit is that we can easily use it for invoking non-member functions without any changes, which we may need to do.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the reasons I prefer not using the tuple is it violates our C++ guidelines for the repo.

I also think this implementation looks much cleaner and easier to understand at a glance.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see anything about tuple violating our C++ guidelines. I assume you may be referring to https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/clr-code-guide.md#-2114-limit-usage-of-standard-template-types-in-shipping-executables. My understanding was that this section was more about stuff that would have parts of the code in the lib. The tuple, at least in this usage case, doesn't require any such code.

We had bad experience with performance of lambdas in the past (@davidwrighton tried to change some huge macros in GC to lambdas), so I was worried that the compiler would not be able to eliminate the calls in this case. Fortunately, it is not that case here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The concern @jkotas has (and the reason for the rules) is about any code that may exist in the headers or any statically-linked portions. Anything in the standard library that is loaded at runtime from the target machine's standard library implementation is fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that's my understanding as well. It would not have been the case here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tuple has code that runs that's defined in the headers, so it meets the definition AFAIK. In practice we'd never have an issue, but my understanding is that we'd rather be more strict here than trying to be more granular header-by-header.

@janvorli
Copy link
Member Author

janvorli commented Nov 4, 2025

Hmm, the new version breaks the interpreter test, I am investigating ...

@janvorli
Copy link
Member Author

janvorli commented Nov 4, 2025

Ah, copy and paste error for the GetMethodDescOfVirtualizedCode

janvorli and others added 2 commits November 4, 2025 16:35
Fix copy and paste error
Removed the CallGetMethodDescOfVirtualizedCode function, which is now a dead code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants