Skip to content

Commit

Permalink
#12 Attempt to rewrite down till we find the expected method
Browse files Browse the repository at this point in the history
  • Loading branch information
sguldmund committed Jan 15, 2024
1 parent ada9c53 commit 5f5a01f
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/Pose/IL/MethodRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Pose.IL
{
internal class MethodRewriter
public class MethodRewriter
{
private static readonly List<OpCode> IgnoredOpCodes = new List<OpCode> { OpCodes.Endfilter, OpCodes.Endfinally };

Expand Down
2 changes: 2 additions & 0 deletions src/Pose/IL/Stubs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ public static DynamicMethod GenerateStubForVirtualCall(MethodInfo method, TypeIn

var ilGenerator = stub.GetILGenerator();

actualMethod = actualMethod ?? method;

if ((actualMethod.GetMethodBody() == null && !actualMethod.IsAbstract) || StubHelper.IsIntrinsic(actualMethod))
{
// Method has no body or is a compiler intrinsic,
Expand Down
74 changes: 74 additions & 0 deletions src/Pose/PoseContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,61 @@
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading.Tasks;
using Pose.IL;

namespace System.Runtime.CompilerServices
{
// AsyncVoidMethodBuilder.cs in your project
public class AsyncTaskMethodBuilder
{
public void AwaitOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter,
ref TStateMachine stateMachine
)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{

}

public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{

}

public void SetStateMachine(IAsyncStateMachine stateMachine) {}

public void SetException(Exception exception) {}

public Task Task => null;

public AsyncTaskMethodBuilder()
=> Console.WriteLine(".ctor");

public static AsyncTaskMethodBuilder Create()
=> new AsyncTaskMethodBuilder();

public void SetResult() => Console.WriteLine("SetResult");

public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
Console.WriteLine("Start");
var methodInfos = stateMachine.GetType().GetMethods(BindingFlags.Instance | BindingFlags.NonPublic);
var methodRewriter = MethodRewriter.CreateRewriter(methodInfos[0], false);
var methodBase = methodRewriter.Rewrite();
stateMachine.MoveNext();
}

// AwaitOnCompleted, AwaitUnsafeOnCompleted, SetException
// and SetStateMachine are empty
}
}

namespace Pose
{
public static class PoseContext
Expand All @@ -30,5 +83,26 @@ public static void Isolate(Action entryPoint, params Shim[] shims)
Console.WriteLine("----------------------------- Invoking ----------------------------- ");
methodInfo.CreateDelegate(delegateType).DynamicInvoke(entryPoint.Target);
}

public static async Task IsolateAsync(Func<Task> entryPoint, params Shim[] shims)
{
if (shims == null || shims.Length == 0)
{
await entryPoint.Invoke();
return;
}

Shims = shims;
StubCache = new Dictionary<MethodBase, DynamicMethod>();

var delegateType = typeof(Func<Task>); //.MakeGenericType(entryPoint.Target.GetType());
var rewriter = MethodRewriter.CreateRewriter(entryPoint.Method, false);
Console.WriteLine("----------------------------- Rewriting ----------------------------- ");
var methodInfo = (MethodInfo)(rewriter.Rewrite());

Console.WriteLine("----------------------------- Invoking ----------------------------- ");
var @delegate = methodInfo.CreateDelegate(delegateType);
@delegate.DynamicInvoke();
}
}
}
27 changes: 26 additions & 1 deletion src/Sandbox/Program.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,38 @@
// See https://aka.ms/new-console-template for more information

using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Pose.IL;

namespace Pose.Sandbox
{
public class Program
{
public static async Task<int> GetAsyncInt() => await Task.FromResult(1);

public static async Task Lol()
{
var asyncInt = await GetAsyncInt();
Console.WriteLine(asyncInt);
}

public static void Main(string[] args)
{
//Lol().GetAwaiter().GetResult();

var shim = Shim
.Replace(() => Program.GetAsyncInt())
.With(() => Task.FromResult(2));

PoseContext.IsolateAsync(
async () =>
{
var @int = await GetAsyncInt();
Console.WriteLine(@int);
}, shim).GetAwaiter().GetResult();
/*
#if NET48
Console.WriteLine("4.8");
var dateTimeShim = Shim.Replace(() => DateTime.Now).With(() => new DateTime(2004, 1, 1));
Expand Down Expand Up @@ -58,7 +83,7 @@ public static void Main(string[] args)
Console.WriteLine(DateTime.Now);
}, dateTimeShim);
#endif

*/
// var dateTimeShim = Shim.Replace(() => T.I).With(() => "L");
// var dateTimeShim1 = Shim.Replace(() => T.Get()).With(() => "Word");
// var inst = new Inst();
Expand Down

0 comments on commit 5f5a01f

Please sign in to comment.