コード例 #1
0
        public override void Emit(EmitContext ec)
        {
            // TODO: Should guard against multiple emits
            base.Emit(ec);

            // Release temporary variable when used
            if (variable != null)
            {
                variable.Release(ec);
            }
        }
コード例 #2
0
        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);
        }