示例#1
0
 /// <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];
 }
示例#2
0
        /// <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;
        }