/// <summary> /// Emits load of optional parameters array on the evaluation stack. /// </summary> /// <param name="node">Instance.</param> /// <param name="builder">An overloads builder.</param> /// <param name="start">An index of the first optional parameter to be loaded into the array (indices start from 0).</param> /// <param name="param"> /// A <see cref="ParameterInfo"/> of the formal parameter of the target method where the array will be passed. /// This information influences conversions all optional parameters. /// </param> /// <param name="optArgCount">Optional argument count (unused).</param> public void EmitLibraryLoadOptArguments(CallSignature /*!*/ node, OverloadsBuilder /*!*/ builder, int start, ParameterInfo /*!*/ param, IPlace optArgCount) { Debug.Assert(start >= 0 && builder != null && param != null && builder.Aux is CodeGenerator); ILEmitter il = builder.IL; Type elem_type = param.ParameterType.GetElementType(); Type array_type = elem_type.MakeArrayType(); // NEW <alem_type>[<parameters count - start>] il.LdcI4(node.Parameters.Length - start); il.Emit(OpCodes.Newarr, elem_type); // loads each optional parameter into the appropriate bucket of the array: for (int i = start; i < node.Parameters.Length; i++) { // <arr>[i - start] il.Emit(OpCodes.Dup); il.LdcI4(i - start); // <parameter value> object type_or_value = EmitLibraryLoadArgument(node, il, i, builder.Aux, param); builder.EmitArgumentConversion(elem_type, type_or_value, false, param, 3); // <arr>[i - start] = <parameter value>; il.Stelem(elem_type); } // <arr> }
/// <summary> /// Emits load of optional parameters array on the evaluation stack. /// </summary> /// <param name="builder">An overloads builder.</param> /// <param name="start">An index of the first optional parameter to be loaded into the array (indices start from 0).</param> /// <param name="param"> /// A <see cref="ParameterInfo"/> of the formal parameter of the target method where the array will be passed. /// This information influences conversions all optional parameters. /// </param> /// <param name="optArgCount">Optional argument count (unused).</param> internal void EmitLibraryLoadOptArguments(OverloadsBuilder /*!*/ builder, int start, ParameterInfo /*!*/ param, IPlace optArgCount) { Debug.Assert(start >= 0 && builder != null && param != null && builder.Aux is CodeGenerator); ILEmitter il = builder.IL; Type elem_type = param.ParameterType.GetElementType(); Type array_type = elem_type.MakeArrayType(); LocalBuilder loc_array = il.DeclareLocal(array_type); LocalBuilder loc_item = il.DeclareLocal(elem_type); // NEW <alem_type>[<parameters count - start>] il.LdcI4(parameters.Count - start); il.Emit(OpCodes.Newarr, elem_type); il.Stloc(loc_array); // loads each optional parameter into the appropriate bucket of the array: for (int i = start; i < parameters.Count; i++) { // item = <parameter value>; object type_or_value = EmitLibraryLoadArgument(il, i, builder.Aux); builder.EmitArgumentConversion(elem_type, type_or_value, false, param); il.Stloc(loc_item); // array[<i-start>] = item; il.Ldloc(loc_array); il.LdcI4(i - start); il.Ldloc(loc_item); il.Stelem(elem_type); } // loads the array: il.Ldloc(loc_array); }