Exemple #1
0
        /// <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);
                }
            }
        }