Skip to content
Merged
Changes from 2 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ public partial class AsyncResumptionStub : ILStubMethod
{
private readonly MethodDesc _owningMethod;
private MethodSignature _signature;
private MethodIL _methodIL;
Comment thread
jkotas marked this conversation as resolved.
Outdated

public AsyncResumptionStub(MethodDesc owningMethod)
{
Debug.Assert(owningMethod.IsAsyncVariant()
|| (owningMethod.IsAsync && !owningMethod.Signature.ReturnsTaskOrValueTask()));
Debug.Assert(owningMethod.IsAsyncCall());
_owningMethod = owningMethod;
}

Expand All @@ -32,22 +32,85 @@ public AsyncResumptionStub(MethodDesc owningMethod)

public override TypeSystemContext Context => _owningMethod.Context;

protected override int ClassCode => unchecked((int)0xa91ac565);

Comment thread
jtschuster marked this conversation as resolved.
Outdated
private MethodSignature InitializeSignature()
{
TypeDesc objectType = Context.GetWellKnownType(WellKnownType.Object);
TypeDesc byrefByte = Context.GetWellKnownType(WellKnownType.Byte).MakeByRefType();
return _signature = new MethodSignature(0, 0, objectType, [objectType, byrefByte]);
}

public override MethodIL EmitIL()
private MethodIL InitializeMethodIL()
{
var emitter = new ILEmitter();
ILCodeStream codeStream = emitter.NewCodeStream();
Debug.Assert(_methodIL == null);
ILEmitter ilEmitter = new ILEmitter();
ILCodeStream ilStream = ilEmitter.NewCodeStream();

// Ported from jitinterface.cpp CEEJitInfo::getAsyncResumptionStub
if (!_owningMethod.Signature.IsStatic)
{
if (_owningMethod.OwningType.IsValueType)
{
ilStream.EmitLdc(0);
ilStream.Emit(ILOpcode.conv_u);
}
else
{
ilStream.Emit(ILOpcode.ldnull);
}
}

foreach (var param in _owningMethod.Signature)
Comment thread
jtschuster marked this conversation as resolved.
Outdated
{
var local = ilEmitter.NewLocal(param);
ilStream.EmitLdLoca(local);
ilStream.Emit(ILOpcode.initobj, ilEmitter.NewToken(param));
ilStream.EmitLdLoc(local);
}
ilStream.Emit(ILOpcode.ldftn, ilEmitter.NewToken(_owningMethod));
Comment thread
jtschuster marked this conversation as resolved.
Outdated
ilStream.Emit(ILOpcode.calli, ilEmitter.NewToken(this.Signature));
Comment thread
jtschuster marked this conversation as resolved.
Outdated

// TODO: match getAsyncResumptionStub from CoreCLR VM
codeStream.EmitCallThrowHelper(emitter, Context.GetHelperEntryPoint("ThrowHelpers"u8, "ThrowNotSupportedException"u8));
bool returnsVoid = _owningMethod.Signature.ReturnType != Context.GetWellKnownType(WellKnownType.Void);
Internal.IL.Stubs.ILLocalVariable resultLocal = default;
Comment thread
MichalStrehovsky marked this conversation as resolved.
Outdated
if (!returnsVoid)
{
resultLocal = ilEmitter.NewLocal(_owningMethod.Signature.ReturnType);
ilStream.EmitStLoc(resultLocal);
}

return emitter.Link(this);
MethodDesc asyncCallContinuation = Context.SystemModule.GetKnownType("System.StubHelpers"u8, "StubHelpers"u8)
Comment thread
jkotas marked this conversation as resolved.
Outdated
.GetKnownMethod("AsyncCallContinuation"u8, null);
Comment thread
jkotas marked this conversation as resolved.
TypeDesc continuation = Context.SystemModule.GetKnownType("System.Runtime.CompilerServices"u8, "Continuation"u8);
var newContinuationLocal = ilEmitter.NewLocal(continuation);
ilStream.Emit(ILOpcode.call, ilEmitter.NewToken(asyncCallContinuation));
ilStream.EmitStLoc(newContinuationLocal);

if (!returnsVoid)
{
var doneResult = ilEmitter.NewCodeLabel();
ilStream.EmitLdLoca(newContinuationLocal);
Comment thread
jtschuster marked this conversation as resolved.
Outdated
ilStream.Emit(ILOpcode.brtrue, doneResult);
ilStream.EmitLdArg(1);
ilStream.EmitLdLoc(resultLocal);
ilStream.Emit(ILOpcode.stobj, ilEmitter.NewToken(_owningMethod.Signature.ReturnType));
ilStream.EmitLabel(doneResult);
}
ilStream.EmitLdLoc(newContinuationLocal);
ilStream.Emit(ILOpcode.ret);

return _methodIL = ilEmitter.Link(this);
}

public override MethodIL EmitIL()
{
return _methodIL ?? InitializeMethodIL();
}
Comment thread
jtschuster marked this conversation as resolved.

protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
{
var othr = (AsyncResumptionStub)other;
return comparer.Compare(_owningMethod, othr._owningMethod);
}
}
}
Loading