private void GenerateConsumeResult(FieldValue result_target, ILGenerator builder, bool load_instance) { var method = TypeBuilder.DefineMethod("ConsumeResult" + result_consumer++, MethodAttributes.Public, typeof(void), new System.Type[] { typeof(object) }); var consume_builder = method.GetILGenerator(); if (result_target != null) { consume_builder.Emit(OpCodes.Ldarg_0); consume_builder.Emit(OpCodes.Ldarg_1); consume_builder.Emit(OpCodes.Stfld, result_target.Field); } LoadTaskMaster(consume_builder); consume_builder.Emit(OpCodes.Ldarg_0); consume_builder.Emit(OpCodes.Callvirt, typeof(TaskMaster).GetMethod("Slot")); consume_builder.Emit(OpCodes.Ret); if (load_instance) { builder.Emit(OpCodes.Ldarg_0); } builder.Emit(OpCodes.Ldftn, method); builder.Emit(OpCodes.Newobj, typeof(ConsumeResult).GetConstructors()[0]); }
/** * Copies the contents of one field to another, boxing or unboxing based on * the field types. */ void CopyField(LoadableValue source, FieldValue target) { CopyField(source, target.Field); }
/** * Generate a function to receive a value and request continued computation from the task master. */ public void GenerateConsumeResult(FieldValue result_target) { GenerateConsumeResult(result_target, Builder, true); }
internal Generator(CompilationUnit owner, TypeBuilder type_builder, bool has_original) { Owner = owner; TypeBuilder = type_builder; // Create fields for all information provided by the caller. state_field = TypeBuilder.DefineField("state", typeof(long), FieldAttributes.Private); task_master = TypeBuilder.DefineField("task_master", typeof(TaskMaster), FieldAttributes.Private); InitialSourceReference = new FieldValue(TypeBuilder.DefineField("source_reference", typeof(SourceReference), FieldAttributes.Private)); InitialContext = new FieldValue(TypeBuilder.DefineField("context", typeof(Context), FieldAttributes.Private)); InitialSelfFrame = new FieldValue(TypeBuilder.DefineField("self", typeof(Frame), FieldAttributes.Private)); InitialContainerFrame = new FieldValue(TypeBuilder.DefineField("container", typeof(Frame), FieldAttributes.Private)); var construct_params = new System.Type[] { typeof(TaskMaster), typeof(SourceReference), typeof(Context), typeof(Frame), typeof(Frame) }; var initial_information = new FieldInfo[] { task_master, InitialSourceReference.Field, InitialContext.Field, InitialSelfFrame.Field, InitialContainerFrame.Field }; // Create a constructor the takes all the state information provided by the // caller and stores it in appropriate fields. var ctor = type_builder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, construct_params); var ctor_builder = ctor.GetILGenerator(); for (var it = 0; it < initial_information.Length; it++) { ctor_builder.Emit(OpCodes.Ldarg_0); ctor_builder.Emit(OpCodes.Ldarg, it + 1); ctor_builder.Emit(OpCodes.Stfld, initial_information[it]); } ctor_builder.Emit(OpCodes.Ldarg_0); ctor_builder.Emit(OpCodes.Ldc_I4_0); ctor_builder.Emit(OpCodes.Stfld, state_field); ctor_builder.Emit(OpCodes.Ret); System.Type[] init_params; if (has_original) { init_params = new System.Type[construct_params.Length + 1]; for (var it = 0; it < construct_params.Length; it++) { init_params[it] = construct_params[it]; } init_params[init_params.Length - 1] = typeof(Computation); } else { init_params = construct_params; } // Create a static method that wraps the constructor. This is needed to create a delegate. Initialiser = type_builder.DefineMethod("Init", MethodAttributes.Public | MethodAttributes.Static, typeof(Computation), init_params); var init_builder = Initialiser.GetILGenerator(); for (var it = 0; it < initial_information.Length; it++) { init_builder.Emit(OpCodes.Ldarg, it); } init_builder.Emit(OpCodes.Newobj, ctor); // If overriding, attach the overriding function to the original computation. if (has_original) { var init_this = init_builder.DeclareLocal(TypeBuilder); init_builder.Emit(OpCodes.Stloc, init_this); init_builder.Emit(OpCodes.Ldarg, initial_information.Length); init_builder.Emit(OpCodes.Ldloc, init_this); GenerateConsumeResult(InitialOriginal, init_builder, false); init_builder.Emit(OpCodes.Callvirt, typeof(Computation).GetMethod("Notify")); init_builder.Emit(OpCodes.Ldloc, init_this); } init_builder.Emit(OpCodes.Ret); // Create a run method with an initial state. Builder = type_builder.DefineMethod("Run", MethodAttributes.Public | MethodAttributes.Virtual, typeof(bool), new System.Type[0]).GetILGenerator(); switch_label = Builder.DefineLabel(); var start_label = Builder.DefineLabel(); entry_points.Add(start_label); Builder.Emit(OpCodes.Br, switch_label); Builder.MarkLabel(start_label); }