Skip to content

Conversation

@soqb
Copy link

@soqb soqb commented Jun 26, 2025

  • New way to track instances of injected classes, allowing injected finalizers to run properly, and fix the memory leaks which the documentation warns of.
  • Consolidate Il2CppObjectBase initialization (and related IL generation) into one cohesive method.
  • See the new documentation for the procedural overview.
  • This also fixes a bug/is a breaking change: the lifetime of managed injected instances is now shorter, meaning that non-injected fields might now be dropped earlier than expected.~
  • Open question: currently, this PR has some trickery to make the managed object's finalizer itself (~Foo()) be the method which is overriden, should we instead make this some public override void Il2CppFinalize() dummy method instead? It likely would make our implementation burden a little easier, and maybe elide the SuppressFinalize trickery, but would be an ergonomics hit.

@ds5678
Copy link
Collaborator

ds5678 commented Jun 27, 2025

Hello 👋

I don't normally work on runtime stuff, so I'm not sure I feel comfortable reviewing your pull request, but it did not go unnoticed.

FYI I'm currently working on the v2 rewrite, which could cause issues for your pull request. I'm looking at getting an implementation for the generation changes pushed soon.

@soqb
Copy link
Author

soqb commented Jun 28, 2025

exciting! could you point me to your work (if available online, no worries if not) so i can see how we intersect?

@ds5678
Copy link
Collaborator

ds5678 commented Jun 28, 2025

exciting! could you point me to your work (if available online, no worries if not) so i can see how we intersect?

Not yet available. I'm going to make a pull request when I push.

@ds5678
Copy link
Collaborator

ds5678 commented Sep 1, 2025

exciting! could you point me to your work (if available online, no worries if not) so i can see how we intersect?

https://github.com/ds5678/Il2CppInterop/tree/v2-rewrite

Copy link
Collaborator

@ds5678 ds5678 left a comment

Choose a reason for hiding this comment

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

Hello! I'm excited for your pull request and want to see it be part of v2.

Comment on lines -393 to -394
public IntPtr MethodInfo;
public Delegate ReferencedDelegate;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm very happy to see this. One of the things in v2 that was bothering me is that I wasn't sure what to do with these fields. I'm introducing a breaking change that injected classes can't have managed state.

Copy link
Author

Choose a reason for hiding this comment

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

yeah i think breaking change is the only way to fix the semantics. i have a branch somewhere for bepinex which fixes it there.

ClassInjector.DerivedConstructorBody(this);
}

private void Il2CppFinalize()
Copy link
Collaborator

Choose a reason for hiding this comment

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

v2 replaces [HideFromIl2Cpp] with an opt-in system. The user indicator for this would be:

[Il2CppMethod(Name = "Finalize")]

Copy link
Author

Choose a reason for hiding this comment

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

not exactly, i think the attribute does make sense for consistency but it would still need special-casing and the injected class' Finalize method would not directly translate to the one defined here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The Name property applies in any situation where an Il2Cpp name differs from the generated name in managed code. In the case of finalizers, the v2 generator appends underscores, which is approximately the same as what you're doing.

public Il2CppInterfaceCollection? Interfaces { get; init; } = null;
}

internal record FinalizerChain(Delegate finalizer, FinalizerChain? next)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I feel like this should just use a primary constructor rather than be a record.


namespace Il2CppInterop.Runtime.InteropTypes;

public class Il2CppObjectBase
Copy link
Collaborator

Choose a reason for hiding this comment

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

Il2CppObjectBase is being removed in v2 in lieu of injecting code directly into Il2CppSystem.Object. As much code as possible should be implemented with extension methods or other helper classes.

Copy link
Author

Choose a reason for hiding this comment

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

what's wrong with Il2CppObjectBase 😭? where will the new Il2CppSystem.Object be defined? will it still have behaviour i can configure (like the finalizer, and initialisation)?

Copy link
Collaborator

@ds5678 ds5678 Sep 2, 2025

Choose a reason for hiding this comment

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

It's not a real type.

Il2Cppmscorlib

Your capabilities should not change.

@soqb
Copy link
Author

soqb commented Sep 2, 2025

i'm a little confused on what the roadmap is with v2. is there an issue or something which lays it out? as a downstream user, i need to know if v2 is "coming soon" or not; are we at that stage of saying "nothing gets merged until v2 because that's top priority"? if so, i can rebase on top of your branch, but if not, i'm also willing to rebase yours on mine once this is merged.

i want to make this as easy a merge as possible for you.

@ds5678 ds5678 added this to the 2.0.0 milestone Sep 2, 2025
@ds5678
Copy link
Collaborator

ds5678 commented Sep 2, 2025

i'm a little confused on what the roadmap is with v2. is there an issue or something which lays it out?

There's a milestone, which includes most of the v2 changes.

as a downstream user, i need to know if v2 is "coming soon" or not

Yes, I'm making a WIP pull request sometime this week.

are we at that stage of saying "nothing gets merged until v2 because that's top priority"?

Yes, that will likely be the next merge. 1.5.1 was released as the "last commit before the massively breaking changes of v2."

if so, i can rebase on top of your branch, but if not, i'm also willing to rebase yours on mine once this is merged.

i want to make this as easy a merge as possible for you.

I still need to:

  • Rebase my branch on the recent commits from 1.5.1
  • Make some generation changes
  • Tidy up my branch
  • Make a pull request

At that point, my branch will still need additional runtime changes, but it'll be safe for you to rebase your changes and make a pull request onto my branch.

@soqb
Copy link
Author

soqb commented Sep 3, 2025

thank you so much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants