Emit() public method

public Emit ( EmitContext ec ) : void
ec EmitContext
return void
Beispiel #1
0
        void EmitMoveNext_NoResumePoints(EmitContext ec, Block original_block)
        {
            ec.EmitThis();
            ec.Emit(OpCodes.Ldfld, storey.PC.Spec);

            ec.EmitThis();
            ec.EmitInt((int)IteratorStorey.State.After);
            ec.Emit(OpCodes.Stfld, storey.PC.Spec);

            // We only care if the PC is zero (start executing) or non-zero (don't do anything)
            ec.Emit(OpCodes.Brtrue, move_next_error);

            iterator_body_end = ec.DefineLabel();

            SymbolWriter.StartIteratorBody(ec);
            original_block.Emit(ec);
            SymbolWriter.EndIteratorBody(ec);

            ec.MarkLabel(iterator_body_end);

            EmitMoveNextEpilogue(ec);

            ec.MarkLabel(move_next_error);

            if (ReturnType.Kind != MemberKind.Void)
            {
                ec.EmitInt(0);
                ec.Emit(OpCodes.Ret);
            }
        }
Beispiel #2
0
        void EmitMoveNext_NoResumePoints(EmitContext ec, Block original_block)
        {
            ec.Emit(OpCodes.Ldarg_0);
            ec.Emit(OpCodes.Ldfld, IteratorHost.PC.Spec);

            ec.Emit(OpCodes.Ldarg_0);
            ec.EmitInt((int)State.After);
            ec.Emit(OpCodes.Stfld, IteratorHost.PC.Spec);

            // We only care if the PC is zero (start executing) or non-zero (don't do anything)
            ec.Emit(OpCodes.Brtrue, move_next_error);

            SymbolWriter.StartIteratorBody(ec);
            original_block.Emit(ec);
            SymbolWriter.EndIteratorBody(ec);

            ec.MarkLabel(move_next_error);
            ec.Emit(OpCodes.Ldc_I4_0);
            ec.Emit(OpCodes.Ret);
        }
Beispiel #3
0
        void EmitMoveNext_NoResumePoints(EmitContext ec, Block original_block)
        {
            ec.Emit (OpCodes.Ldarg_0);
            ec.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec);

            ec.Emit (OpCodes.Ldarg_0);
            ec.EmitInt ((int) State.After);
            ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);

            // We only care if the PC is zero (start executing) or non-zero (don't do anything)
            ec.Emit (OpCodes.Brtrue, move_next_error);

            SymbolWriter.StartIteratorBody (ec);
            original_block.Emit (ec);
            SymbolWriter.EndIteratorBody (ec);

            ec.MarkLabel (move_next_error);
            ec.Emit (OpCodes.Ldc_I4_0);
            ec.Emit (OpCodes.Ret);
        }
Beispiel #4
0
        internal void EmitMoveNext(EmitContext ec, Block original_block)
        {
            move_next_ok = ec.DefineLabel ();
            move_next_error = ec.DefineLabel ();

            if (resume_points == null) {
                EmitMoveNext_NoResumePoints (ec, original_block);
                return;
            }

            current_pc = ec.GetTemporaryLocal (TypeManager.uint32_type);
            ec.Emit (OpCodes.Ldarg_0);
            ec.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec);
            ec.Emit (OpCodes.Stloc, current_pc);

            // We're actually in state 'running', but this is as good a PC value as any if there's an abnormal exit
            ec.Emit (OpCodes.Ldarg_0);
            ec.EmitInt ((int) State.After);
            ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);

            Label [] labels = new Label [1 + resume_points.Count];
            labels [0] = ec.DefineLabel ();

            bool need_skip_finally = false;
            for (int i = 0; i < resume_points.Count; ++i) {
                ResumableStatement s = resume_points [i];
                need_skip_finally |= s is ExceptionStatement;
                labels [i+1] = s.PrepareForEmit (ec);
            }

            if (need_skip_finally) {
                skip_finally = ec.GetTemporaryLocal (TypeManager.bool_type);
                ec.Emit (OpCodes.Ldc_I4_0);
                ec.Emit (OpCodes.Stloc, skip_finally);
            }

            SymbolWriter.StartIteratorDispatcher (ec);
            ec.Emit (OpCodes.Ldloc, current_pc);
            ec.Emit (OpCodes.Switch, labels);

            ec.Emit (OpCodes.Br, move_next_error);
            SymbolWriter.EndIteratorDispatcher (ec);

            ec.MarkLabel (labels [0]);

            SymbolWriter.StartIteratorBody (ec);
            original_block.Emit (ec);
            SymbolWriter.EndIteratorBody (ec);

            SymbolWriter.StartIteratorDispatcher (ec);

            ec.Emit (OpCodes.Ldarg_0);
            ec.EmitInt ((int) State.After);
            ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);

            ec.MarkLabel (move_next_error);
            ec.EmitInt (0);
            ec.Emit (OpCodes.Ret);

            ec.MarkLabel (move_next_ok);
            ec.Emit (OpCodes.Ldc_I4_1);
            ec.Emit (OpCodes.Ret);

            SymbolWriter.EndIteratorDispatcher (ec);
        }
Beispiel #5
0
        internal void EmitMoveNext(EmitContext ec, Block original_block)
        {
            ILGenerator ig = ec.ig;

            move_next_ok    = ig.DefineLabel();
            move_next_error = ig.DefineLabel();

            if (resume_points == null)
            {
                EmitMoveNext_NoResumePoints(ec, original_block);
                return;
            }

            current_pc = ec.GetTemporaryLocal(TypeManager.uint32_type);
            ig.Emit(OpCodes.Ldarg_0);
            ig.Emit(OpCodes.Ldfld, IteratorHost.PC.FieldBuilder);
            ig.Emit(OpCodes.Stloc, current_pc);

            // We're actually in state 'running', but this is as good a PC value as any if there's an abnormal exit
            ig.Emit(OpCodes.Ldarg_0);
            IntConstant.EmitInt(ig, (int)State.After);
            ig.Emit(OpCodes.Stfld, IteratorHost.PC.FieldBuilder);

            Label [] labels = new Label [1 + resume_points.Count];
            labels [0] = ig.DefineLabel();

            bool need_skip_finally = false;

            for (int i = 0; i < resume_points.Count; ++i)
            {
                ResumableStatement s = (ResumableStatement)resume_points [i];
                need_skip_finally |= s is ExceptionStatement;
                labels [i + 1]     = s.PrepareForEmit(ec);
            }

            if (need_skip_finally)
            {
                skip_finally = ec.GetTemporaryLocal(TypeManager.bool_type);
                ig.Emit(OpCodes.Ldc_I4_0);
                ig.Emit(OpCodes.Stloc, skip_finally);
            }

            SymbolWriter.StartIteratorDispatcher(ec.ig);
            ig.Emit(OpCodes.Ldloc, current_pc);
            ig.Emit(OpCodes.Switch, labels);

            ig.Emit(OpCodes.Br, move_next_error);
            SymbolWriter.EndIteratorDispatcher(ec.ig);

            ig.MarkLabel(labels [0]);

            SymbolWriter.StartIteratorBody(ec.ig);
            original_block.Emit(ec);
            SymbolWriter.EndIteratorBody(ec.ig);

            SymbolWriter.StartIteratorDispatcher(ec.ig);

            ig.Emit(OpCodes.Ldarg_0);
            IntConstant.EmitInt(ig, (int)State.After);
            ig.Emit(OpCodes.Stfld, IteratorHost.PC.FieldBuilder);

            ig.MarkLabel(move_next_error);
            ig.Emit(OpCodes.Ldc_I4_0);
            ig.Emit(OpCodes.Ret);

            ig.MarkLabel(move_next_ok);
            ig.Emit(OpCodes.Ldc_I4_1);
            ig.Emit(OpCodes.Ret);

            SymbolWriter.EndIteratorDispatcher(ec.ig);
        }