示例#1
0
        /* Performs indirect loading of value
         * (corresponds to CILPE.CFG.LoadIndirect class)
         */
        public void Perform_LoadIndirect(Type type, out Exception exc)
        {
            exc = null;
            Value val = Pop();

            if (val is NullValue)
            {
                exc = new NullReferenceException();
            }
            else
            {
                if (!(val is PointerValue))
                {
                    throw new InvalidOperandException();
                }

                object obj = (val as PointerValue).GetReferencedObject();

                if (type == typeof(object))
                {
                    Push(new ObjectReferenceValue(obj));
                }
                else
                {
                    StructValue.TypeIndex typeIndex = StructValue.getTypeIndex(type);

                    if (typeIndex != StructValue.TypeIndex.INVALID)
                    {
                        StructValue.TypeIndex objTypeIndex = StructValue.getTypeIndex(obj.GetType());

                        if (!compareTypes(objTypeIndex, typeIndex))
                        {
                            throw new InvalidOperandException();
                        }

                        Push(new StructValue(obj as ValueType));
                    }
                    else if (type.IsValueType)
                    {
                        if (type != obj.GetType())
                        {
                            throw new InvalidOperandException();
                        }

                        Push(new StructValue(obj as ValueType));
                    }
                    else
                    {
                        throw new InvalidLoadIndirectException();
                    }
                }
            }
        }
示例#2
0
        /* Performs loading of array element
         * (corresponds to CILPE.CFG.LoadElement class)
         */
        public void Perform_LoadElement(Type type, out Exception exc)
        {
            int   index = popArrayIndex();
            Array array = popArray(out exc);

            if (exc == null)
            {
                if (type != typeof(object))
                {
                    StructValue.TypeIndex typeIndex    = StructValue.getTypeIndex(type);
                    StructValue.TypeIndex arrTypeIndex =
                        StructValue.getTypeIndex(array.GetType().GetElementType());

                    if (!compareTypes(arrTypeIndex, typeIndex))
                    {
                        exc = new ArrayTypeMismatchException();
                    }
                }

                if (exc == null)
                {
                    object elem = null;
                    try
                    {
                        elem = array.GetValue(index);
                    }
                    catch (IndexOutOfRangeException e)
                    {
                        exc = e;
                    }

                    if (exc == null)
                    {
                        if (StructValue.getTypeIndex(type) != StructValue.TypeIndex.INVALID)
                        {
                            Push(new StructValue(elem as ValueType));
                        }
                        else
                        {
                            if (elem != null)
                            {
                                Push(new ObjectReferenceValue(elem));
                            }
                            else
                            {
                                Push(new NullValue());
                            }
                        }
                    }
                }
            }
        }
示例#3
0
        /* Performs conversion of primitive value on top of the stack
         * (corresponds to CILPE.CFG.ConvertValue class)
         */
        public void Perform_ConvertValue(Type type, bool overflow, bool unsigned,
                                         out Exception exc)
        {
            exc = null;
            Value val = Pop();

            if (!(val is StructValue && (val as StructValue).IsPrimitive))
            {
                throw new InvalidOperandException();
            }

            StructValue primVal = val as StructValue;

            StructValue.TypeIndex typeIndex    = StructValue.getTypeIndex(type),
                                  valTypeIndex = primVal.getTypeIndex();

            if (!overflow && unsigned && typeIndex != StructValue.TypeIndex.FLOAT64 ||
                overflow && typeIndex == StructValue.TypeIndex.FLOAT32 ||
                overflow && typeIndex == StructValue.TypeIndex.FLOAT64)
            {
                throw new InvalidConvertOpException();
            }

            object res;
            bool   success = DataModelUtils.Convert(
                (int)typeIndex, overflow, unsigned,
                primVal.Obj, (int)valTypeIndex,
                out res
                );

            if (!success)
            {
                exc = res as Exception;
            }
            else
            {
                push(new StructValue(res as ValueType));
            }
        }
示例#4
0
        private bool compareTypes(StructValue.TypeIndex type1, StructValue.TypeIndex type2)
        {
            if (type1 == StructValue.TypeIndex.UNATIVEINT &&
                type2 == StructValue.TypeIndex.NATIVEINT)
            {
                type2 = StructValue.TypeIndex.UNATIVEINT;
            }

            if (type1 == StructValue.TypeIndex.CHAR &&
                type2 == StructValue.TypeIndex.UINT16)
            {
                type2 = StructValue.TypeIndex.CHAR;
            }

            if (type1 == StructValue.TypeIndex.BOOL &&
                type2 == StructValue.TypeIndex.INT8)
            {
                type2 = StructValue.TypeIndex.BOOL;
            }

            return(type1 == type2);
        }
示例#5
0
        /* Performs unary operation on the value on top of the stack
         * (corresponds to CILPE.CFG.UnaryOp class)
         */
        public void Perform_UnaryOp(UnaryOp.ArithOp op)
        {
            Value     val = Pop();
            ValueType res = null;

            if (val is StructValue && (val as StructValue).IsPrimitive)
            {
                StructValue strVal = val as StructValue;

                ValueType             obj       = strVal.Obj;
                StructValue.TypeIndex typeIndex = strVal.getTypeIndex();

                if (!DataModelUtils.Unary((int)op, obj, (int)typeIndex, out res))
                {
                    throw new InvalidOperandException();
                }
            }
            else
            {
                throw new InvalidOperandException();
            }

            push(new StructValue(res));
        }
示例#6
0
        /* Performs binary operation on two values on top of the stack
         * (corresponds to CILPE.CFG.BinaryOp class)
         */
        public void Perform_BinaryOp(BinaryOp.ArithOp op, bool overflow, bool unsigned,
                                     out Exception exc)
        {
            exc = null;

            /* Determining category of binary operation */
            OpCategory category = getCategory(op, overflow, unsigned);

            if (category == OpCategory.InvalidOp)
            {
                throw new InvalidBinaryOpException();
            }

            /* Getting operands from stack */
            Value val1, val2;

            val2 = Pop();
            val1 = Pop();

            /* Performing binary operation */
            object res = null;

            if (val1 is StructValue && val2 is StructValue)
            {
                StructValue.TypeIndex
                    typeA = (val1 as StructValue).getTypeIndex(),
                    typeB = (val2 as StructValue).getTypeIndex();

                if (typeA == StructValue.TypeIndex.INVALID ||
                    typeB == StructValue.TypeIndex.INVALID)
                {
                    throw new InvalidOperandException();
                }

                ValueType
                    a = (val1 as StructValue).Obj,
                    b = (val2 as StructValue).Obj;

                int  operandsKind = 0;
                bool success      = true;

                if (category == OpCategory.ShiftOp) /* shl, shr, shr_un */
                {
                    if (typeA == StructValue.TypeIndex.FLOAT64 ||
                        typeB == StructValue.TypeIndex.FLOAT64 ||
                        typeB == StructValue.TypeIndex.INT64)
                    {
                        throw new InvalidOperandException();
                    }

                    operandsKind = ((typeB == StructValue.TypeIndex.INT32) ? 0 : 3) + (int)typeA;
                    DataModelUtils.ShiftOp((int)op, unsigned, a, b, operandsKind, out res);
                }
                else
                {
                    if (typeA == typeB)
                    {
                        operandsKind = (int)typeA;
                    }
                    else if (typeA == StructValue.TypeIndex.INT32 && typeB == StructValue.TypeIndex.NATIVEINT)
                    {
                        operandsKind = 4;
                    }
                    else if (typeA == StructValue.TypeIndex.NATIVEINT && typeB == StructValue.TypeIndex.INT32)
                    {
                        operandsKind = 5;
                    }
                    else
                    {
                        throw new InvalidOperandException();
                    }

                    switch (category)
                    {
                    case OpCategory.NumericOp:     /* add, div, mul, rem, sub */
                        success = DataModelUtils.NumericOp((int)op, a, b, operandsKind, out res);
                        break;

                    case OpCategory.ComparisonOp:     /* ceq, cgt, cgt.un, clt, clt.un */
                        DataModelUtils.ComparisonOp((int)op, unsigned, a, b, operandsKind, out res);
                        break;

                    case OpCategory.IntegerOp:     /* and, div.un, or, rem.un, xor */
                    case OpCategory.OverflowOp:    /* add.ovf, add.ovf.un, mul.ovf, mul.ovf.un, sub.ovf, sub.ovf.un */
                        if (operandsKind == 3)
                        {
                            throw new InvalidOperandException();
                        }

                        success = DataModelUtils.IntOvfOp((int)op, unsigned, a, b, operandsKind, out res);
                        break;
                    }
                }

                if (!success)
                {
                    exc = res as Exception;
                    res = null;
                }
            }
            else if (op == BinaryOp.ArithOp.CEQ)
            {
                if ((val1 is NullValue || val1 is ObjectReferenceValue) &&
                    (val2 is NullValue || val2 is ObjectReferenceValue) ||
                    (val1 is NullValue || val1 is PointerValue) &&
                    (val2 is NullValue || val2 is PointerValue))
                {
                    res = Equals(val1, val2) ? (Int32)1 : (Int32)0;
                }
                else
                {
                    throw new InvalidOperandException();
                }
            }
            else if (op == BinaryOp.ArithOp.CGT)
            {
                if (val1 is ObjectReferenceValue && val2 is NullValue && unsigned)
                {
                    res = (Int32)1;
                }
                else if (val1 is NullValue && val2 is NullValue)
                {
                    res = (Int32)0;
                }
                else if (val1 is PointerValue && val2 is NullValue)
                {
                    res = (Int32)1;
                }
                else
                {
                    throw new InvalidOperandException();
                }
            }
            else if (op == BinaryOp.ArithOp.CLT)
            {
                if (val1 is NullValue && val2 is ObjectReferenceValue && unsigned)
                {
                    res = (Int32)1;
                }
                else if (val1 is NullValue && val2 is NullValue)
                {
                    res = (Int32)0;
                }
                else if (val1 is NullValue && val2 is PointerValue)
                {
                    res = (Int32)1;
                }
                else
                {
                    throw new InvalidOperandException();
                }
            }
            else
            {
                throw new InvalidOperandException();
            }

            if (res != null)
            {
                push(new StructValue(res as ValueType));
            }
        }