/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, IMethodCompiler compiler) { base.Validate(ctx, compiler); StackTypeCode result = StackTypeCode.Unknown; switch (_opcode) { case OpCode.Add: result = _addTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; case OpCode.Sub: result = _subTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; default: result = _operandTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; } if (StackTypeCode.Unknown == result) { throw new InvalidOperationException("Invalid operand types passed to " + _opcode); } SigType resultType; if (result != StackTypeCode.Ptr) { resultType = Operand.SigTypeFromStackType(result); } else { // Copy the pointer element type PtrSigType op0 = ctx.Operand1.Type as PtrSigType; PtrSigType op1 = ctx.Operand2.Type as PtrSigType; if (op0 != null) { resultType = new PtrSigType(op0.CustomMods, op0.ElementType); } else if (op1 != null) { resultType = new PtrSigType(op1.CustomMods, op1.ElementType); } else { throw new InvalidOperationException(); } } ctx.Result = compiler.CreateTemporary(resultType); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, IMethodCompiler compiler) { base.Validate(ctx, compiler); // If we're ldind.i8, fix an IL deficiency that the result may be U8 if (opcode == OpCode.Ldind_i8 && this.typeRef.Type == CilElementType.I8) { SigType opType = ctx.Operand1.Type; RefSigType rst = opType as RefSigType; PtrSigType ptr = opType as PtrSigType; if (rst != null && rst.ElementType.Type == CilElementType.U8 || ptr != null && ptr.ElementType.Type == CilElementType.U8) { ctx.Result = compiler.CreateTemporary(BuiltInSigType.UInt64); } } }