Exemplo n.º 1
0
        /// <summary>
        /// Runs the specified compiler.
        /// </summary>
        void IMethodCompilerStage.Run()
        {
            // Handler Code
            foreach (ExceptionHandlingClause clause in methodCompiler.ExceptionClauseHeader.Clauses)
            {
                if (clause.ExceptionHandler == ExceptionHandlerType.Exception)
                {
                    var typeToken = new Token(clause.ClassToken);

                    RuntimeType type = methodCompiler.Method.Module.GetType(typeToken);

                    var block = FindBlock(clause.HandlerOffset);

                    var context = new Context(instructionSet, block).InsertBefore();

                    SigType sigType = new ClassSigType(typeToken);
                    Operand exceptionObject = methodCompiler.CreateTemporary(sigType);

                    context.SetInstruction(IR.Instruction.ExceptionPrologueInstruction, exceptionObject);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(Context ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            SigType sigType = typeRef;

            // Do we have a type?
            if (sigType == null)
            {
                // No, retrieve a type reference from the immediate argument
                Token token = decoder.DecodeTokenType();
                sigType = new ClassSigType(token);
                ctx.Other = sigType;
            }
            else
                ctx.Other = TypeReference;

            // Push the loaded value
            ctx.Result = LoadInstruction.CreateResultOperand(decoder, Operand.StackTypeFromSigType(sigType), sigType);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(Context ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            SigType sigType = elementType;

            // Do we have a type?
            if (sigType == null)
            {
                // No, retrieve a type reference from the immediate argument
                Token token = decoder.DecodeTokenType();
                sigType = new ClassSigType(token);
            }

            StackTypeCode stackType = Operand.StackTypeFromSigType(sigType);
            Operand result = LoadInstruction.CreateResultOperand(decoder, stackType, sigType);

            ctx.Result = result;
        }
Exemplo n.º 4
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;
        }