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); } }
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); }
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); }
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); }
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); }