public void EmitAwaitOnCompletedDynamic(EmitContext ec, FieldExpr awaiter)
{
var critical = Module.PredefinedTypes.ICriticalNotifyCompletion;
if (!critical.Define())
{
throw new NotImplementedException();
}
var temp_critical = new LocalTemporary(critical.TypeSpec);
var label_critical = ec.DefineLabel();
var label_end = ec.DefineLabel();
//
// Special path for dynamic awaiters
//
// var awaiter = this.$awaiter as ICriticalNotifyCompletion;
// if (awaiter == null) {
// var completion = (INotifyCompletion) this.$awaiter;
// this.$builder.AwaitOnCompleted (ref completion, ref this);
// } else {
// this.$builder.AwaitUnsafeOnCompleted (ref awaiter, ref this);
// }
//
awaiter.Emit(ec);
ec.Emit(OpCodes.Isinst, critical.TypeSpec);
temp_critical.Store(ec);
temp_critical.Emit(ec);
ec.Emit(OpCodes.Brtrue_S, label_critical);
var temp = new LocalTemporary(Module.PredefinedTypes.INotifyCompletion.TypeSpec);
awaiter.Emit(ec);
ec.Emit(OpCodes.Castclass, temp.Type);
temp.Store(ec);
EmitOnCompleted(ec, temp, false);
temp.Release(ec);
ec.Emit(OpCodes.Br_S, label_end);
ec.MarkLabel(label_critical);
EmitOnCompleted(ec, temp_critical, true);
ec.MarkLabel(label_end);
temp_critical.Release(ec);
}