/// <summary> /// Sets the stack parameter. /// </summary> /// <param name="index">The index.</param> /// <param name="param">The param.</param> /// <param name="type">The type.</param> /// <returns></returns> public ParameterOperand SetStackParameter(int index, RuntimeParameter param, SigType type) { parameters[index] = new ParameterOperand(architecture.StackFrameRegister, param, type); return parameters[index]; }
/// <summary> /// Retrieves the parameter operand at the specified <paramref name="index"/>. /// </summary> /// <param name="index">The index of the parameter operand to retrieve.</param> /// <returns>The operand at the specified index.</returns> /// <exception cref="System.ArgumentOutOfRangeException">The <paramref name="index"/> is not valid.</exception> public Operand GetParameterOperand(int index) { // HACK: Returning a new instance here breaks object identity. We should reuse operands, // which represent the same memory location. If we need to move a variable in an optimization // stage to a different memory location, it should actually be a new one so sharing object // only saves runtime space/perf. MethodSignature sig = method.Signature; if (sig.HasThis || sig.HasExplicitThis) { if (index == 0) { var classSigType = new ClassSigType(type.Token); var signatureType = this.Method.DeclaringType.ContainsOpenGenericParameters ? assemblyCompiler.GenericTypePatcher.PatchSignatureType(this.Method.Module, this.Method.DeclaringType as CilGenericType, type.Token) : classSigType; return new ParameterOperand( architecture.StackFrameRegister, new RuntimeParameter(@"this", 2, ParameterAttributes.In), signatureType); } // Decrement the index, as the caller actually wants a real parameter --index; } // A normal argument, decode it... IList<RuntimeParameter> methodParameters = method.Parameters; Debug.Assert(methodParameters != null, @"Method doesn't have arguments."); Debug.Assert(index < methodParameters.Count, @"Invalid argument index requested."); if (methodParameters == null || methodParameters.Count <= index) throw new ArgumentOutOfRangeException(@"index", index, @"Invalid parameter index"); Operand parameter = null; if (parameters.Count > index) parameter = parameters[index]; if (parameter == null) { SigType parameterType = sig.Parameters[index]; if (parameterType is GenericInstSigType && (parameterType as GenericInstSigType).ContainsGenericParameters) { var genericInstSigType = parameterType as GenericInstSigType; parameterType = assemblyCompiler.GenericTypePatcher.PatchSignatureType(typeSystem.InternalTypeModule, Method.DeclaringType, genericInstSigType.BaseType.Token); } parameter = new ParameterOperand(architecture.StackFrameRegister, methodParameters[index], parameterType); parameters[index] = parameter; } return parameter; }