Skip to content
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

Synchronizing dumper with monomod and fixing ILLabel dumping #118

Merged
merged 5 commits into from
Jan 10, 2025

Conversation

kohanis
Copy link
Contributor

@kohanis kohanis commented Jul 24, 2024

No description provided.

Harmony/Internal/Util/CecilEmitter.cs Outdated Show resolved Hide resolved
Harmony/Internal/Util/CecilEmitter.cs Outdated Show resolved Hide resolved
ImplAttributes = MethodImplAttributes.IL | MethodImplAttributes.Managed,
DeclaringType = td,
HasThis = false
HasThis = false,
NoInlining = true
Copy link
Contributor

Choose a reason for hiding this comment

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

Justification?

Copy link
Contributor

@Meivyn Meivyn Dec 17, 2024

Choose a reason for hiding this comment

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

Dumps are broken without this when you try to dump methods that are inlined, or when dumping a transpiler that is postfixed, or situations like that. Same thing for relinker below. At least this is what this PR is supposed to fix, and it did when I tested it.

For context, this is what happened when I tried to dump a postfix that was inlined:

image

Original method:

public static NoteLineLayer GetNoteLineLayer(int lineLayer)
{
  switch (lineLayer)
  {
    case 0:
      return NoteLineLayer.Base;
    case 1:
      return NoteLineLayer.Upper;
    case 2:
      return NoteLineLayer.Top;
    default:
      return NoteLineLayer.Base;
  }
}

Postfix:

[HarmonyPatch(typeof(BeatmapDataLoaderVersion3.BeatmapDataLoader.ObstacleConverter), nameof(BeatmapDataLoaderVersion3.BeatmapDataLoader.ObstacleConverter.GetNoteLineLayer))]
internal class BeatmapDataLoaderObstacleConverterGetNoteLineLayerPatch
{
    private static void Postfix(ref NoteLineLayer __result, int lineLayer)
    {
        if (lineLayer > 2)
        {
            __result = (NoteLineLayer)lineLayer;
        }
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Monomod changes

Harmony/Internal/Util/CecilEmitter.cs Outdated Show resolved Hide resolved
Harmony/Internal/Util/CecilEmitter.cs Outdated Show resolved Hide resolved
Harmony/Internal/Util/CecilEmitter.cs Outdated Show resolved Hide resolved
Comment on lines +58 to +100
Relinker relinker = (mtp, _) =>
{
if (mtp == md)
return clone!;
if (mtp is MethodReference mr)
{
if (mr.FullName == md.FullName
&& mr.DeclaringType.FullName == md.DeclaringType.FullName
&& mr.DeclaringType.Scope.Name == md.DeclaringType.Scope.Name)
return clone!;
}
return module.ImportReference(mtp);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Justification?

Copy link
Contributor

@Meivyn Meivyn Dec 18, 2024

Choose a reason for hiding this comment

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

Updated from reorg: https://github.com/MonoMod/MonoMod/blob/26a0a4d22fcd233dd22db4fd034cb3ac41420fd4/src/MonoMod.Utils/DMDGenerators/DMDCecilGenerator.cs#L72-L83

Which is also the same for the double Public, and everything else but the label stuff. Label stuff specifically addressed the issue I mentioned above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Monomod changes

@Meivyn
Copy link
Contributor

Meivyn commented Dec 18, 2024

While it fixed some of the cases I encountered previously, it seems to still be causing issues.

image

Patch:

private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
    // Replaces the obstacle width.
    return new CodeMatcher(instructions)
        .MatchEndForward(
            new CodeMatch(i => i.opcode == OpCodes.Callvirt && ((MethodBase)i.operand).Name == $"get_{nameof(ObstacleController.width)}"),
            new CodeMatch(OpCodes.Conv_R4),
            new CodeMatch())
        .ThrowIfInvalid()
        .Insert(Transpilers.EmitDelegate<Func<float, float>>(obstacleWidth =>
        {
            if (!Plugin.active || obstacleWidth is < 1000 and > -1000)
            {
                return obstacleWidth;
            }

            if (obstacleWidth <= -1000)
            {
                obstacleWidth += 2000;
            }

            return (obstacleWidth - 1000) / 1000;
        }))
        .InstructionEnumeration();
}

Original:

public ObstacleSpawnData GetObstacleSpawnData(ObstacleData obstacleData)
{
    Vector3 obstacleOffset = this.GetObstacleOffset(obstacleData.lineIndex, obstacleData.lineLayer);
    obstacleOffset.y += this._jumpOffsetYProvider.jumpOffsetY;
    obstacleOffset.y = Mathf.Max(obstacleOffset.y, this._verticalObstaclePosY);
    float num = Mathf.Min((float)obstacleData.height * StaticBeatmapObjectSpawnMovementData.layerHeight,     this._obstacleTopPosY - obstacleOffset.y);
    float num2 = (float)obstacleData.width * 0.6f;
    obstacleOffset.x += (num2 - 0.6f) * 0.5f;
    return new ObstacleSpawnData(obstacleOffset, num2, num);
}

@ds5678
Copy link
Contributor

ds5678 commented Dec 18, 2024

@Meivyn If you wrote unit tests demonstrating your bug, that would be exceedingly useful and would significantly increase the likelihood that fixes get merged.

@Meivyn
Copy link
Contributor

Meivyn commented Dec 18, 2024

It's actually because of Transpilers.EmitDelegate here, because passing a static method with OpCodes.Call works fine. To write unit tests you must narrow down the issue, and that's not something I was able to achieve with the previous issue. And now it seems that the issue might be in how this helper method is handled.

This PR was opened after a conversation with them that started here: https://discord.com/channels/623153565053222947/1128639196169510942/1265164603151618129

@kohanis kohanis changed the title Fixing and synchronizing dumper Synchronizing dumper with monomod and fixing ILLabel dumping Dec 26, 2024
@kohanis
Copy link
Contributor Author

kohanis commented Dec 26, 2024

Split into commits. Reworked fix a bit. Added a test. Left comments because they are in the original and have a contextual meaning

@kohanis
Copy link
Contributor Author

kohanis commented Dec 26, 2024

CI failed on setup-dotnet, huh)

Harmony/Internal/Util/CecilEmitter.cs Outdated Show resolved Hide resolved
Harmony/Internal/Util/CecilEmitter.cs Outdated Show resolved Hide resolved
Harmony/Internal/Util/CecilEmitter.cs Show resolved Hide resolved
@ManlyMarco ManlyMarco merged commit 6746d17 into BepInEx:master Jan 10, 2025
2 checks passed
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.

4 participants