Example #1
0
 /// <summary>
 /// Creates a decoder.
 /// </summary>
 /// <param name="log">A log to use for error and warning messages.</param>
 /// <param name="typeResolver">A read-only type resolver for resolving types.</param>
 /// <param name="codec">A Flame IR codec.</param>
 public DecoderState(
     ILog log,
     ReadOnlyTypeResolver typeResolver,
     IrCodec codec)
     : this(log, typeResolver, codec, TypeParent.Nothing)
 {
 }
 /// <summary>
 /// Creates a type system based on a core library type resolver.
 /// </summary>
 /// <param name="corlibTypeResolver">
 /// A type resolver for the core library, which supplies the
 /// types in the type system.
 /// </param>
 public CorlibTypeEnvironment(ReadOnlyTypeResolver corlibTypeResolver)
 {
     this.CorlibTypeResolver = corlibTypeResolver;
     this.arrayTypeCache     = new InterningCache <ClrArrayType>(
         new RankClrArrayTypeComparer());
     this.createArrayBaseTypes = new Lazy <Func <int, IGenericParameter, IReadOnlyList <IType> > >(
         ResolveArrayBaseTypes);
     this.signedIntegerTypes    = new Lazy <Dictionary <int, IType> >(ResolveSignedIntegerTypes);
     this.unsignedIntegerTypes  = new Lazy <Dictionary <int, IType> >(ResolveUnsignedIntegerTypes);
     this.voidType              = new Lazy <IType>(() => ResolveSystemType(nameof(Void)));
     this.float32Type           = new Lazy <IType>(() => ResolveSystemType(nameof(Single)));
     this.float64Type           = new Lazy <IType>(() => ResolveSystemType(nameof(Double)));
     this.charType              = new Lazy <IType>(() => ResolveSystemType(nameof(Char)));
     this.stringType            = new Lazy <IType>(() => ResolveSystemType(nameof(String)));
     this.intPtrType            = new Lazy <IType>(() => ResolveSystemType(nameof(IntPtr)));
     this.uintPtrType           = new Lazy <IType>(() => ResolveSystemType(nameof(UIntPtr)));
     this.objectType            = new Lazy <IType>(() => ResolveSystemType(nameof(Object)));
     this.typeTokenType         = new Lazy <IType>(() => ResolveSystemType(nameof(RuntimeTypeHandle)));
     this.fieldTokenType        = new Lazy <IType>(() => ResolveSystemType(nameof(RuntimeFieldHandle)));
     this.methodTokenType       = new Lazy <IType>(() => ResolveSystemType(nameof(RuntimeMethodHandle)));
     this.capturedExceptionType = new Lazy <IType>(
         () => CorlibTypeResolver.ResolveTypes(
             new SimpleName("ExceptionDispatchInfo")
             .Qualify("ExceptionServices")
             .Qualify("Runtime")
             .Qualify("System"))
         .FirstOrDefault());
 }
        /// <summary>
        /// Creates CIL prototype exception specification rules.
        /// </summary>
        /// <param name="corlibTypeResolver">
        /// A type resolver for the core library (corlib.dll) that
        /// defines well-known exception types.
        /// </param>
        /// <returns>Prototype exception specification rules.</returns>
        public static RuleBasedPrototypeExceptionSpecs Create(
            ReadOnlyTypeResolver corlibTypeResolver)
        {
            var result = new RuleBasedPrototypeExceptionSpecs(
                RuleBasedPrototypeExceptionSpecs.Default);

            // We know the type of exception thrown by null checks:
            // it's System.NullReferenceException.
            var nullRefException = corlibTypeResolver.ResolveTypes(
                new SimpleName(nameof(NullReferenceException))
                .Qualify(nameof(System)))
                                   .Single();

            // Resolve other well-known exception types.
            var outOfRangeException = corlibTypeResolver.ResolveTypes(
                new SimpleName(nameof(IndexOutOfRangeException))
                .Qualify(nameof(System)))
                                      .Single();

            var arrayTypeMismatchException = corlibTypeResolver.ResolveTypes(
                new SimpleName(nameof(ArrayTypeMismatchException))
                .Qualify(nameof(System)))
                                             .Single();

            // Refine null check exception types.
            result.Register <GetFieldPointerPrototype>(
                new NullCheckExceptionSpecification(0, nullRefException));
            result.Register <NewDelegatePrototype>(
                proto => proto.Lookup == MethodLookup.Virtual
                    ? new NullCheckExceptionSpecification(0, nullRefException)
                    : ExceptionSpecification.NoThrow);
            result.Register <UnboxPrototype>(
                new NullCheckExceptionSpecification(0, nullRefException));

            // Array intrinsics are worth refining, too.
            result.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.GetElementPointer),
                ExceptionSpecification.Union.Create(
                    new NullCheckExceptionSpecification(0, nullRefException),
                    ExceptionSpecification.Exact.Create(outOfRangeException),
                    ExceptionSpecification.Exact.Create(arrayTypeMismatchException)));
            result.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.LoadElement),
                ExceptionSpecification.Union.Create(
                    new NullCheckExceptionSpecification(0, nullRefException),
                    ExceptionSpecification.Exact.Create(outOfRangeException)));
            result.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.StoreElement),
                ExceptionSpecification.Union.Create(
                    new NullCheckExceptionSpecification(0, nullRefException),
                    ExceptionSpecification.Exact.Create(outOfRangeException),
                    ExceptionSpecification.Exact.Create(arrayTypeMismatchException)));
            result.Register(
                ArrayIntrinsics.Namespace.GetIntrinsicName(ArrayIntrinsics.Operators.GetLength),
                new NullCheckExceptionSpecification(0, nullRefException));

            return(result);
        }
Example #4
0
 /// <summary>
 /// Creates a decoder.
 /// </summary>
 /// <param name="log">A log to use for error and warning messages.</param>
 /// <param name="typeResolver">A read-only type resolver for resolving types.</param>
 /// <param name="codec">A Flame IR codec.</param>
 /// <param name="scope">The decoder's scope.</param>
 private DecoderState(
     ILog log,
     ReadOnlyTypeResolver typeResolver,
     IrCodec codec,
     TypeParent scope)
 {
     this.Log             = log;
     this.TypeResolver    = typeResolver;
     this.Codec           = codec;
     this.Scope           = scope;
     this.typeCache       = new ConcurrentDictionary <LNode, IType>();
     this.TypeMemberIndex = new Index <IType, UnqualifiedName, ITypeMember>(
         type =>
         type.Fields
         .Concat <ITypeMember>(type.Properties)
         .Concat <ITypeMember>(type.Methods)
         .Select(member =>
                 new KeyValuePair <UnqualifiedName, ITypeMember>(
                     member.Name,
                     member)));
 }
Example #5
0
 /// <summary>
 /// Creates a decoder that relies on the default codec.
 /// </summary>
 /// <param name="log">A log to use for error and warning messages.</param>
 /// <param name="typeResolver">A read-only type resolver for resolving types.</param>
 public DecoderState(ILog log, ReadOnlyTypeResolver typeResolver)
     : this(log, typeResolver, IrCodec.Default)
 {
 }
Example #6
0
        /// <summary>
        /// Resolves dependencies that Brainfuck programs use to accept input and produce output.
        /// </summary>
        /// <param name="environment">
        /// The type environment to resolve dependencies in.
        /// </param>
        /// <param name="binder">
        /// A type resolver for resolving dependencies with.
        /// </param>
        /// <param name="log">A log to send messages to.</param>
        /// <returns>
        /// Brainfuck IO dependencies.
        /// </returns>
        public static Dependencies Resolve(
            TypeEnvironment environment,
            ReadOnlyTypeResolver binder,
            ILog log)
        {
            var consoleType = binder.ResolveTypes(new SimpleName("Console").Qualify("System")).FirstOrDefault();

            if (consoleType == null)
            {
                log.Log(
                    new LogEntry(
                        Severity.Warning,
                        "console not found",
                        "no class named 'System.Console' was not found. IO calls will be replaced with constants."));
                return(new Dependencies(environment, null, null));
            }
            else
            {
                var writeMethod = consoleType.Methods.FirstOrDefault(
                    method => method.Name.ToString() == "Write" &&
                    method.IsStatic &&
                    method.ReturnParameter.Type == environment.Void &&
                    method.Parameters.Count == 1 &&
                    method.Parameters[0].Type == environment.Char);

                var readMethod = consoleType.Methods.FirstOrDefault(
                    method => method.Name.ToString() == "Read" &&
                    method.IsStatic &&
                    method.ReturnParameter.Type == environment.Int32 &&
                    method.Parameters.Count == 0);

                if (writeMethod != null)
                {
                    log.Log(
                        new LogEntry(
                            Severity.Info,
                            "output method found",
                            "found 'void System.Console.Write(char)'."));
                }
                else
                {
                    log.Log(
                        new LogEntry(
                            Severity.Warning,
                            "output method not found",
                            "couldn't find 'void System.Console.Write(char)'. No output will be written."));
                }
                if (readMethod != null)
                {
                    log.Log(
                        new LogEntry(
                            Severity.Info,
                            "input method found",
                            "found 'int System.Console.Read()'."));
                }
                else
                {
                    log.Log(
                        new LogEntry(
                            Severity.Warning,
                            "input method not found",
                            "couldn't find 'char System.Console.Read()'. No input will be read."));
                }

                return(new Dependencies(environment, readMethod, writeMethod));
            }
        }