Пример #1
0
        static RuleBasedPrototypeExceptionSpecs()
        {
            Default = new RuleBasedPrototypeExceptionSpecs();

            // Instruction prototypes that never throw.
            Default.Register <AllocaArrayPrototype>(ExceptionSpecification.NoThrow);
            Default.Register <AllocaPrototype>(ExceptionSpecification.NoThrow);
            Default.Register <BoxPrototype>(ExceptionSpecification.NoThrow);
            Default.Register <ConstantPrototype>(ExceptionSpecification.NoThrow);
            Default.Register <CopyPrototype>(ExceptionSpecification.NoThrow);
            Default.Register <DynamicCastPrototype>(ExceptionSpecification.NoThrow);
            Default.Register <GetStaticFieldPointerPrototype>(ExceptionSpecification.NoThrow);
            Default.Register <LoadPrototype>(ExceptionSpecification.NoThrow);
            Default.Register <ReinterpretCastPrototype>(ExceptionSpecification.NoThrow);
            Default.Register <StorePrototype>(ExceptionSpecification.NoThrow);

            // Instruction prototypes that may throw because of implicit null checks.
            Default.Register <GetFieldPointerPrototype>(
                new NullCheckExceptionSpecification(0, ExceptionSpecification.ThrowAny));
            Default.Register <NewDelegatePrototype>(
                proto => proto.Lookup == MethodLookup.Virtual
                    ? new NullCheckExceptionSpecification(0, ExceptionSpecification.ThrowAny)
                    : ExceptionSpecification.NoThrow);
            Default.Register <UnboxPrototype>(
                new NullCheckExceptionSpecification(0, ExceptionSpecification.ThrowAny));

            // Call-like instruction prototypes.
            Default.Register <CallPrototype>(
                proto => proto.Lookup == MethodLookup.Static
                    ? proto.Callee.GetExceptionSpecification()
                    : ExceptionSpecification.ThrowAny);
            Default.Register <NewObjectPrototype>(
                proto => proto.Constructor.GetExceptionSpecification());
            Default.Register <IndirectCallPrototype>(ExceptionSpecification.ThrowAny);

            // Unchecked arithmetic intrinsics never throw.
            foreach (var name in ArithmeticIntrinsics.Operators.All)
            {
                Default.Register(
                    ArithmeticIntrinsics.GetArithmeticIntrinsicName(name, false),
                    ExceptionSpecification.NoThrow);
            }

            // Array intrinsics are a little more complicated.
            // TODO: model bounds checks somehow.
            Default.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.GetElementPointer),
                ExceptionSpecification.ThrowAny);
            Default.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.LoadElement),
                ExceptionSpecification.ThrowAny);
            Default.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.StoreElement),
                ExceptionSpecification.ThrowAny);
            Default.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.GetLength),
                new NullCheckExceptionSpecification(0, ExceptionSpecification.ThrowAny));
            Default.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.NewArray),
                ExceptionSpecification.NoThrow);

            // Exception intrinsics.
            Default.Register(
                ExceptionIntrinsics.Namespace.GetIntrinsicName(ExceptionIntrinsics.Operators.Capture),
                ExceptionSpecification.NoThrow);
            Default.Register(
                ExceptionIntrinsics.Namespace.GetIntrinsicName(ExceptionIntrinsics.Operators.GetCapturedException),
                ExceptionSpecification.NoThrow);
            Default.Register(
                ExceptionIntrinsics.Namespace.GetIntrinsicName(ExceptionIntrinsics.Operators.Rethrow),
                ExceptionSpecification.ThrowAny);
            Default.Register(
                ExceptionIntrinsics.Namespace.GetIntrinsicName(ExceptionIntrinsics.Operators.Throw),
                proto => ExceptionSpecification.Exact.Create(proto.ParameterTypes[0]));

            // Object intrinsics.
            // TODO: model exception thrown by type check.
            Default.Register(
                ObjectIntrinsics.Namespace.GetIntrinsicName(ObjectIntrinsics.Operators.UnboxAny),
                ExceptionSpecification.ThrowAny);

            // Memory intrinsics.
            Default.Register(
                MemoryIntrinsics.Namespace.GetIntrinsicName(MemoryIntrinsics.Operators.AllocaPinned),
                ExceptionSpecification.NoThrow);
        }
Пример #2
0
        static RuleBasedPrototypeMemorySpecs()
        {
            Default = new RuleBasedPrototypeMemorySpecs();

            Default.Register <AllocaArrayPrototype>(MemorySpecification.Nothing);
            Default.Register <AllocaPrototype>(MemorySpecification.Nothing);
            Default.Register <BoxPrototype>(MemorySpecification.Nothing);
            Default.Register <ConstantPrototype>(MemorySpecification.Nothing);
            Default.Register <CopyPrototype>(MemorySpecification.Nothing);
            Default.Register <DynamicCastPrototype>(MemorySpecification.Nothing);
            Default.Register <GetStaticFieldPointerPrototype>(MemorySpecification.Nothing);
            Default.Register <ReinterpretCastPrototype>(MemorySpecification.Nothing);
            Default.Register <GetFieldPointerPrototype>(MemorySpecification.Nothing);
            Default.Register <NewDelegatePrototype>(MemorySpecification.Nothing);
            Default.Register <UnboxPrototype>(MemorySpecification.Nothing);

            // Mark volatile loads and stores as unknown to ensure that they are never reordered
            // with regard to other memory operations.
            // TODO: is this really how we should represent volatility?
            Default.Register <LoadPrototype>(proto =>
                                             proto.IsVolatile ? MemorySpecification.Unknown : MemorySpecification.ArgumentRead.Create(0));
            Default.Register <StorePrototype>(proto =>
                                              proto.IsVolatile ? MemorySpecification.Unknown : MemorySpecification.ArgumentWrite.Create(0));

            // Call-like instruction prototypes.
            Default.Register <CallPrototype>(
                proto => proto.Lookup == MethodLookup.Static
                    ? proto.Callee.GetMemorySpecification()
                    : MemorySpecification.Unknown);
            Default.Register <NewObjectPrototype>(
                proto => proto.Constructor.GetMemorySpecification());
            Default.Register <IndirectCallPrototype>(MemorySpecification.Unknown);

            // Arithmetic intrinsics never read or write.
            foreach (var name in ArithmeticIntrinsics.Operators.All)
            {
                Default.Register(
                    ArithmeticIntrinsics.GetArithmeticIntrinsicName(name, false),
                    MemorySpecification.Nothing);
                Default.Register(
                    ArithmeticIntrinsics.GetArithmeticIntrinsicName(name, true),
                    MemorySpecification.Nothing);
            }

            // Array intrinsics.
            Default.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.GetElementPointer),
                MemorySpecification.Nothing);
            Default.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.LoadElement),
                MemorySpecification.UnknownRead);
            Default.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.StoreElement),
                MemorySpecification.UnknownWrite);
            Default.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.GetLength),
                MemorySpecification.Nothing);
            Default.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.NewArray),
                MemorySpecification.Nothing);

            // Exception intrinsics.
            Default.Register(
                ExceptionIntrinsics.Namespace.GetIntrinsicName(ExceptionIntrinsics.Operators.GetCapturedException),
                MemorySpecification.UnknownRead);

            // Object intrinsics.
            Default.Register(
                ObjectIntrinsics.Namespace.GetIntrinsicName(ObjectIntrinsics.Operators.UnboxAny),
                MemorySpecification.UnknownRead);

            // Memory intrinsics.
            Default.Register(
                MemoryIntrinsics.Namespace.GetIntrinsicName(MemoryIntrinsics.Operators.AllocaPinned),
                MemorySpecification.Nothing);
        }