Example #1
0
        protected static void GenerateCodeForArguments(ILGenerator gen, CodeFlow cf, MethodBase member, SpelNode[] arguments)
        {
            var paramDescriptors = CodeFlow.ToDescriptors(member.GetParameterTypes());
            var isVarargs        = member.IsVarArgs();

            if (isVarargs)
            {
                var childCount = arguments.Length;

                // The final parameter may or may not need packaging into an array, or nothing may
                // have been passed to satisfy the varargs and so something needs to be built.
                int p;

                // Fulfill all the parameter requirements except the last one
                for (p = 0; p < paramDescriptors.Length - 1; p++)
                {
                    GenerateCodeForArgument(gen, cf, arguments[p], paramDescriptors[p]);
                }

                var lastChild = childCount == 0 ? null : arguments[childCount - 1];
                var arrayType = paramDescriptors[paramDescriptors.Length - 1];

                // Determine if the final passed argument is already suitably packaged in array
                // form to be passed to the method
                if (lastChild != null && arrayType.Equals(lastChild.ExitDescriptor))
                {
                    GenerateCodeForArgument(gen, cf, lastChild, paramDescriptors[p]);
                }
                else
                {
                    var arrElemType = arrayType.Value.GetElementType();
                    var arrElemDesc = new TypeDescriptor(arrElemType);

                    gen.Emit(OpCodes.Ldc_I4, childCount - p);
                    gen.Emit(OpCodes.Newarr, arrElemType);

                    // Package up the remaining arguments into the array
                    var arrayindex = 0;
                    while (p < childCount)
                    {
                        var child = arguments[p];
                        gen.Emit(OpCodes.Dup);
                        gen.Emit(OpCodes.Ldc_I4, arrayindex++);
                        GenerateCodeForArgument(gen, cf, child, arrElemDesc);
                        gen.Emit(GetStelemInsn(arrElemType));
                        p++;
                    }
                }
            }
            else
            {
                for (var i = 0; i < paramDescriptors.Length; i++)
                {
                    GenerateCodeForArgument(gen, cf, arguments[i], paramDescriptors[i]);
                }
            }
        }