Esempio n. 1
0
        public void PeekWriteArrayType(int n, TypeRef expType)
        {
            var type = PeekType(n);
            var s    = type.Style(RootEnv);

            if (s is NullTypeStyle)
            {
                // No-op.
                // If stack entry is generalized it must become an array type
            }
            else if (s is ArrayTypeStyle)
            {
                // If stack entry is generalized it must remain an array type
                expType = expType.ToRunTimeType(RootEnv, false);
                type    = type.Arguments[0];
                if (!expType.IsAssignableTo(RootEnv, type))
                {
                    throw new InvalidOperationException("array element type is not assignable from expected type");
                }
            }
            else
            {
                // Parameter types not allowed
                throw new InvalidOperationException("stack entry is not an array type");
            }
        }
Esempio n. 2
0
        // ----------------------------------------------------------------------
        // Stack type constraints
        // ----------------------------------------------------------------------

        private void SetUpperBound(int n, TypeRef type, BoolRef changed)
        {
            if (n >= Depth)
            {
                throw new InvalidOperationException("stack is too shallow");
            }
            innerState.Value.Stack[n].SetUpperBound(RootEnv, type.ToRunTimeType(RootEnv, true), changed);
        }
Esempio n. 3
0
        public bool PeekDereferencableExpectedType(int n, TypeRef expType, bool canBeStruct, BoolRef changed)
        {
            expType = expType.ToRunTimeType(RootEnv, false);
            var type = PeekType(n);
            var s    = type.Style(RootEnv);

            if (s is NullTypeStyle)
            {
                // Stack entry will remain a referece type (and thus never a pointer).
                // 'null' can be statically dereferenced if we are expecting a reference type, though
                // of course this will cause a null reference exception at runtime
                if (!(expType.Style(RootEnv) is ReferenceTypeStyle))
                {
                    throw new InvalidOperationException("expected type is not a referece type");
                }
                // Stack type cannot be refined above expected reference type
                SetUpperBound(n, expType, changed);
                // Not dereferencing a pointer
                return(false);
            }
            else if (s is UnmanagedPointerTypeStyle)
            {
                throw new InvalidOperationException("unmananaged pointer");
            }
            else if (s is ManagedPointerTypeStyle)
            {
                // Stack entry will remain a pointer of this type, so no need to impose upper bound
                if (!type.Arguments[0].IsAssignableTo(RootEnv, expType))
                {
                    throw new InvalidOperationException
                              ("managed pointer element type is not assignable to expected type");
                }
                // Dereferencing a pointer
                return(true);
            }
            else
            {
                // If stack entry is a value type it will remain a value type, so test is stable under generalization
                if (!canBeStruct && s is ValueTypeStyle)
                {
                    throw new InvalidOperationException
                              ("stack entry is a value type, but value types cannot be the target of field pointers");
                }
                // Values and objects can be dereferenced if they are compatible with expected type
                // Parameter types are not allowed
                if (!(s is ReferenceTypeStyle) && !(s is ValueTypeStyle))
                {
                    throw new InvalidOperationException("stack entry is not a value or reference type");
                }
                // Stack type cannot be refined above expected type
                SetUpperBound(n, expType, changed);
                // Not dereferencing a pointer
                return(false);
            }
        }
Esempio n. 4
0
        public void PeekBoxedType(int n, TypeRef expType, BoolRef changed)
        {
            var type = PeekType(n);
            var s    = type.Style(RootEnv);

            if (s is NullTypeStyle)
            {
                // No-op.
                // Will fail at runtime, but still ok.
                // If stack entry is generalized, it must go directly to Object.
            }
            else if (s is ReferenceTypeStyle)
            {
                if (s is ObjectTypeStyle)
                {
                    // This stack entry can never be refined away from object
                    return;
                }
                if (!(s is BoxTypeStyle))
                {
                    // Parameter types not allowed
                    throw new InvalidOperationException("stack entry is not object or a boxed type");
                }
                if (expType.Style(RootEnv) is NullableTypeStyle)
                {
                    // Account for null -> no-value coercion
                    expType = expType.Arguments[0];
                }
                expType = expType.ToRunTimeType(RootEnv, false);
                if (!type.Arguments[0].IsEquivalentTo(RootEnv, expType))
                {
                    throw new InvalidOperationException("boxed element type is not equivalent to expected type");
                }
                // Box types are NOT invariant, so need to impose upper bound
                SetUpperBound(n, RootEnv.Global.BoxTypeConstructorRef.ApplyTo(expType), changed);
            }
            else
            {
                // Parameter types not allowed
                throw new InvalidOperationException("stack entry is not object or a boxed type");
            }
        }
Esempio n. 5
0
        public void PeekWritePointerType(int n, TypeRef expType)
        {
            var type = PeekType(n);
            var s    = type.Style(RootEnv);

            if (s is UnmanagedPointerTypeStyle)
            {
                throw new InvalidOperationException("unmanaged pointer");
            }
            if (!(s is ManagedPointerTypeStyle))
            {
                throw new InvalidOperationException("stack entry is not a managed pointer type");
            }
            // Parameter types not allowed.
            // Stack entry will remain a pointer to this type, so no need to impose upper bound, and
            // following check is stable under stack refinement.
            if (!(expType.ToRunTimeType(RootEnv, false).IsAssignableTo(RootEnv, type.Arguments[0])))
            {
                throw new InvalidOperationException("pointer element type is not assignable from expected type");
            }
        }
Esempio n. 6
0
        public void PeekReadArrayType(int n, TypeRef expType, bool isExact)
        {
            var type = PeekType(n);
            var s    = type.Style(RootEnv);

            if (s is NullTypeStyle)
            {
                // No-op
                // If stack entry is generalized it must become an array
            }
            else if (s is ArrayTypeStyle)
            {
                // If stack entry is generalized it must remain an array type
                expType = expType.ToRunTimeType(RootEnv, false);
                type    = type.Arguments[0];
                if (isExact)
                {
                    // WARNING: Test may prematurely fail since expType may be revised downwards
                    // TODO: Delay test till final pass?
                    if (!type.IsEquivalentTo(RootEnv, expType))
                    {
                        throw new InvalidOperationException
                                  ("array element type is not equivalent to expected type");
                    }
                }
                else
                {
                    if (!type.IsAssignableTo(RootEnv, expType))
                    {
                        throw new InvalidOperationException("array element type is not assignable to expected type");
                    }
                }
            }
            else
            {
                // Parameter types not allowed
                throw new InvalidOperationException("stack entry is not an array type");
            }
        }
Esempio n. 7
0
 public MachineState PopPushType(int n, TypeRef type, PointsTo pointsTo)
 {
     return(PopPush(n, new StackEntryState(type.ToRunTimeType(RootEnv, true), pointsTo)));
 }