Skip to content

Instantly share code, notes, and snippets.

@Emik03
Last active January 11, 2023 16:37
Show Gist options
  • Save Emik03/d88efe49a874b7d5f45e4bfb96fa541f to your computer and use it in GitHub Desktop.
Save Emik03/d88efe49a874b7d5f45e4bfb96fa541f to your computer and use it in GitHub Desktop.
From Emik.Morsels, requires a reference to it and FodyHelpers on .NET 5.0+. https://github.com/Emik03/Emik.Morsels
#region Emik.Unlicense
// <copyright file="op_Equality.NET.cs" company="Emik">
// Copyright (c) Emik.
// This is free and unencumbered software released into the public domain.
//
// Anyone is free to copy, modify, publish, use, compile, sell, or
// distribute this software, either in source code form or as a compiled
// binary, for any purpose, commercial or non-commercial, and by any
// means.
//
// In jurisdictions that recognize copyright laws, the author or authors
// of this software dedicate any and all copyright interest in the
// software to the public domain. We make this dedication for the benefit
// of the public at large and to the detriment of our heirs and
// successors. We intend this dedication to be an overt act of
// relinquishment in perpetuity of all present and future rights to this
// software under copyright law.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// For more information, please refer to <https://unlicense.org>
// </copyright>
#endregion
using static Mono.Cecil.MethodAttributes;
using static Mono.Cecil.Cil.OpCodes;
static void Add(TypeDefinition type)
{
var module = type.Module ?? throw Unreachable;
var boolean = Get(module, "System.Boolean");
MethodDefinition method = new("op_Equality", Public | RTSpecialName | Static, boolean);
method.CustomAttributes?.Add(new(Inline(module)));
var methods = type.Methods ?? throw Unreachable;
var body = method.Body;
var il = body?.GetILProcessor() ?? throw Unreachable;
body.MaxStackSize = 8;
methods.Add(method);
2.For(_ => method.Parameters?.Add(new(type)));
new[] { Ldarg_0, Ldarg_1, Ceq, Ret }.For(x => il.Emit(x));
}
static MethodDefinition Inline(ModuleDefinition module)
{
var attribute = Get(module, "System.Attribute");
var none = Get(module, "System.Void");
TypeDefinition inline = new("InlineMethod", "InlineAttribute", default, attribute);
MethodDefinition constructor = new(".ctor", Public | RTSpecialName, none);
constructor.Body?.GetILProcessor()?.Emit(Ret);
inline.Methods?.Add(constructor);
module.Types?.Add(inline);
return constructor;
}
static TypeDefinition Get(ModuleDefinition module, string name) =>
module.ManyOrEmpty(x => x.Types).First(x => x.FullName == name);
Func(Console.ReadLine)
.Forever()
.Select(Invoke)
.Filter()
.Select(AssemblyDefinition.ReadAssembly)
.Nth(..1)
.Lazily(x => Add(Get(x.MainModule ?? throw Unreachable, "System.Type")))
.Lazily(x => x.Write($"Divorce.{x.MainModule?.Name}.dll"))
.Enumerate();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment