/// <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); } } }
/// <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); }
/// <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; }
/// <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; }