예제 #1
0
        private static BoundExpression GetCustomTypeInfoPayload(LocalSymbol local, SyntaxNode syntax, CSharpCompilation compilation, out bool hasCustomTypeInfoPayload)
        {
            var byteArrayType = ArrayTypeSymbol.CreateSZArray(
                compilation.Assembly,
                compilation.GetSpecialType(SpecialType.System_Byte));

            var bytes = compilation.GetCustomTypeInfoPayload(local.Type, customModifiersCount: 0, refKind: RefKind.None);

            hasCustomTypeInfoPayload = bytes != null;
            if (!hasCustomTypeInfoPayload)
            {
                return(new BoundLiteral(syntax, ConstantValue.Null, byteArrayType));
            }

            var byteType = byteArrayType.ElementType;
            var intType  = compilation.GetSpecialType(SpecialType.System_Int32);

            var numBytes         = bytes.Count;
            var initializerExprs = ArrayBuilder <BoundExpression> .GetInstance(numBytes);

            foreach (var b in bytes)
            {
                initializerExprs.Add(new BoundLiteral(syntax, ConstantValue.Create(b), byteType));
            }

            var lengthExpr = new BoundLiteral(syntax, ConstantValue.Create(numBytes), intType);

            return(new BoundArrayCreation(
                       syntax,
                       ImmutableArray.Create <BoundExpression>(lengthExpr),
                       new BoundArrayInitialization(syntax, initializerExprs.ToImmutableAndFree()),
                       byteArrayType));
        }
예제 #2
0
        internal override TypeSymbol GetSZArrayTypeSymbol(PEModuleSymbol moduleSymbol, TypeSymbol elementType, ImmutableArray <ModifierInfo <TypeSymbol> > customModifiers)
        {
            if (elementType is UnsupportedMetadataTypeSymbol)
            {
                return(elementType);
            }

            return(ArrayTypeSymbol.CreateSZArray(moduleSymbol.ContainingAssembly, CreateType(elementType, customModifiers)));
        }
예제 #3
0
            public override Symbol VisitArrayType(ArrayTypeSymbol symbol)
            {
                var translatedElementType = (TypeSymbol)this.Visit(symbol.ElementType);
                var translatedModifiers   = VisitCustomModifiers(symbol.CustomModifiers);

                if (symbol.IsSZArray)
                {
                    return(ArrayTypeSymbol.CreateSZArray(symbol.BaseTypeNoUseSiteDiagnostics.ContainingAssembly, translatedElementType, translatedModifiers));
                }

                return(ArrayTypeSymbol.CreateMDArray(symbol.BaseTypeNoUseSiteDiagnostics.ContainingAssembly, translatedElementType, symbol.Rank, symbol.Sizes, symbol.LowerBounds, translatedModifiers));
            }
예제 #4
0
        internal SynthesizedAttributeData SynthesizeTupleNamesAttribute(TypeSymbol type)
        {
            Debug.Assert((object)type != null);
            Debug.Assert(type.ContainsTuple());

            var stringType = GetSpecialType(SpecialType.System_String);

            Debug.Assert((object)stringType != null);
            var names = TupleNamesEncoder.Encode(type, stringType);

            Debug.Assert(!names.IsDefault, "should not need the attribute when no tuple names");

            var stringArray = ArrayTypeSymbol.CreateSZArray(stringType.ContainingAssembly, stringType, customModifiers: ImmutableArray <CustomModifier> .Empty);
            var args        = ImmutableArray.Create(new TypedConstant(stringArray, names));

            return(TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_TupleElementNamesAttribute__ctorTransformNames, args));
        }
예제 #5
0
        private ArrayTypeSymbol DecodeArrayType(ArrayTypeSymbol type)
        {
            var decodedElementType = DecodeType(type.ElementType);

            return(ReferenceEquals(decodedElementType, type)
                ? type
                : type.IsSZArray
                    ? ArrayTypeSymbol.CreateSZArray(_containingAssembly,
                                                    decodedElementType,
                                                    type.CustomModifiers)
                    : ArrayTypeSymbol.CreateMDArray(_containingAssembly,
                                                    decodedElementType,
                                                    type.Rank,
                                                    type.Sizes,
                                                    type.LowerBounds,
                                                    type.CustomModifiers));
        }
예제 #6
0
            public override Symbol VisitArrayType(ArrayTypeSymbol symbol)
            {
                var otherElementType = (TypeSymbol)this.Visit(symbol.ElementType);

                if ((object)otherElementType == null)
                {
                    // For a newly added type, there is no match in the previous generation, so it could be null.
                    return(null);
                }
                var otherModifiers = VisitCustomModifiers(symbol.CustomModifiers);

                if (symbol.IsSZArray)
                {
                    return(ArrayTypeSymbol.CreateSZArray(_otherAssembly, otherElementType, otherModifiers));
                }

                return(ArrayTypeSymbol.CreateMDArray(_otherAssembly, otherElementType, symbol.Rank, symbol.Sizes, symbol.LowerBounds, otherModifiers));
            }
예제 #7
0
        private static ImmutableArray <MethodSymbol> GetAdditionalNullableAttributeConstructors(
            CSharpCompilation compilation,
            NamedTypeSymbol containingType,
            DiagnosticBag diagnostics)
        {
            var boolType = compilation.GetSpecialType(SpecialType.System_Boolean);

            Binder.ReportUseSiteDiagnostics(boolType, diagnostics, Location.None);
            var boolArray = TypeSymbolWithAnnotations.Create(
                ArrayTypeSymbol.CreateSZArray(
                    boolType.ContainingAssembly,
                    TypeSymbolWithAnnotations.Create(boolType)));

            return(ImmutableArray.Create <MethodSymbol>(
                       new SynthesizedEmbeddedAttributeConstructorSymbol(
                           containingType,
                           m => ImmutableArray.Create(SynthesizedParameterSymbol.Create(m, boolArray, 0, RefKind.None)))));
        }
예제 #8
0
        /// <summary>
        /// Given a type <paramref name="type"/>, which is either dynamic type OR is a constructed type with dynamic type present in it's type argument tree,
        /// returns a synthesized DynamicAttribute with encoded dynamic transforms array.
        /// </summary>
        /// <remarks>This method is port of AttrBind::CompileDynamicAttr from the native C# compiler.</remarks>
        internal SynthesizedAttributeData SynthesizeDynamicAttribute(TypeSymbol type, int customModifiersCount, RefKind refKindOpt = RefKind.None)
        {
            Debug.Assert((object)type != null);
            Debug.Assert(type.ContainsDynamic());

            if (type.IsDynamic() && refKindOpt == RefKind.None && customModifiersCount == 0)
            {
                return(TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_DynamicAttribute__ctor));
            }
            else
            {
                NamedTypeSymbol booleanType = GetSpecialType(SpecialType.System_Boolean);
                Debug.Assert((object)booleanType != null);
                var transformFlags = DynamicTransformsEncoder.Encode(type, booleanType, customModifiersCount, refKindOpt);
                var boolArray      = ArrayTypeSymbol.CreateSZArray(booleanType.ContainingAssembly, booleanType, customModifiers: ImmutableArray <CustomModifier> .Empty);
                var arguments      = ImmutableArray.Create <TypedConstant>(new TypedConstant(boolArray, transformFlags));
                return(TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_DynamicAttribute__ctorTransformFlags, arguments));
            }
        }
예제 #9
0
        private ArrayTypeSymbol TransformArrayType(ArrayTypeSymbol arrayType)
        {
            var flag = ConsumeFlag();

            Debug.Assert(!flag);

            if (!HandleCustomModifiers(arrayType.ElementTypeWithAnnotations.CustomModifiers.Length))
            {
                return(null);
            }

            TypeSymbol transformedElementType = TransformType(arrayType.ElementType);

            if ((object)transformedElementType == null)
            {
                return(null);
            }

            return(TypeSymbol.Equals(
                       transformedElementType,
                       arrayType.ElementType,
                       TypeCompareKind.ConsiderEverything2
                       )
              ? arrayType
              : arrayType.IsSZArray
                  ? ArrayTypeSymbol.CreateSZArray(
                       _containingAssembly,
                       arrayType.ElementTypeWithAnnotations.WithTypeAndModifiers(
                           transformedElementType,
                           arrayType.ElementTypeWithAnnotations.CustomModifiers
                           )
                       )
                  : ArrayTypeSymbol.CreateMDArray(
                       _containingAssembly,
                       arrayType.ElementTypeWithAnnotations.WithTypeAndModifiers(
                           transformedElementType,
                           arrayType.ElementTypeWithAnnotations.CustomModifiers
                           ),
                       arrayType.Rank,
                       arrayType.Sizes,
                       arrayType.LowerBounds
                       ));
        }
예제 #10
0
        private ArrayTypeSymbol TransformArrayType(ArrayTypeSymbol arrayType)
        {
            var flag = ConsumeFlag();

            Debug.Assert(!flag);

            if (!HandleCustomModifiers(arrayType.CustomModifiers.Length))
            {
                return(null);
            }

            TypeSymbol transformedElementType = TransformType(arrayType.ElementType);

            if ((object)transformedElementType == null)
            {
                return(null);
            }

            return(transformedElementType == arrayType.ElementType ?
                   arrayType :
                   arrayType.IsSZArray?
                   ArrayTypeSymbol.CreateSZArray(_containingAssembly, transformedElementType, arrayType.CustomModifiers) :
                       ArrayTypeSymbol.CreateMDArray(_containingAssembly, transformedElementType, arrayType.Rank, arrayType.Sizes, arrayType.LowerBounds, arrayType.CustomModifiers));
        }
        /// <summary>
        /// Create real CIL entry point, where it calls given method.
        /// </summary>
        internal void CreateEntryPoint(MethodSymbol method, DiagnosticBag diagnostic)
        {
            // "static int Main(string[] args)"
            var realmethod = new SynthesizedMethodSymbol(this.ScriptType, "Main", true, false, _compilation.CoreTypes.Int32, Accessibility.Private);

            realmethod.SetParameters(new SynthesizedParameterSymbol(realmethod, ArrayTypeSymbol.CreateSZArray(this.Compilation.SourceAssembly, this.Compilation.CoreTypes.String), 0, RefKind.None, "args"));

            //
            var body = MethodGenerator.GenerateMethodBody(this, realmethod,
                                                          (il) =>
            {
                var types      = this.Compilation.CoreTypes;
                var methods    = this.Compilation.CoreMethods;
                var args_place = new ParamPlace(realmethod.Parameters[0]);

                //
                this.EmitBootstrap(il);

                // int exitcode = 0;
                var exitcode_loc = il.LocalSlotManager.AllocateSlot(types.Int32.Symbol, LocalSlotConstraints.None);
                il.EmitIntConstant(0);
                il.EmitLocalStore(exitcode_loc);

                // create Context
                var ctx_loc = il.LocalSlotManager.AllocateSlot(types.Context.Symbol, LocalSlotConstraints.None);
                var ex_loc  = il.LocalSlotManager.AllocateSlot(types.Exception.Symbol, LocalSlotConstraints.None);
                var onUnhandledException_method = types.Context.Symbol.LookupMember <MethodSymbol>("OnUnhandledException");

                if (_compilation.Options.OutputKind == OutputKind.ConsoleApplication)
                {
                    // CreateConsole(string mainscript, params string[] args)
                    var create_method = types.Context.Symbol.LookupMember <MethodSymbol>("CreateConsole", m =>
                    {
                        return
                        (m.ParameterCount == 2 &&
                         m.Parameters[0].Type == types.String &&            // string mainscript
                         m.Parameters[1].Type == args_place.Type);          // params string[] args
                    });
                    Debug.Assert(create_method != null);

                    il.EmitStringConstant(EntryPointScriptName(method));        // mainscript
                    args_place.EmitLoad(il);                                    // args

                    il.EmitOpCode(ILOpCode.Call, +2);
                    il.EmitToken(create_method, null, diagnostic);
                }
                else
                {
                    // CreateEmpty(args)
                    MethodSymbol create_method = types.Context.Symbol.LookupMember <MethodSymbol>("CreateEmpty");
                    Debug.Assert(create_method != null);
                    Debug.Assert(create_method.ParameterCount == 1);
                    Debug.Assert(create_method.Parameters[0].Type == args_place.Type);
                    args_place.EmitLoad(il);        // args
                    il.EmitOpCode(ILOpCode.Call, +1);
                    il.EmitToken(create_method, null, diagnostic);
                }

                il.EmitLocalStore(ctx_loc);

                // Template:
                // try { Main(...); } catch (ScriptDiedException) { } catch (Exception) { ... } finally { ctx.Dispose(); }

                il.OpenLocalScope(ScopeType.TryCatchFinally);       // try { try ... } finally {}
                il.OpenLocalScope(ScopeType.Try);
                {
                    // IL requires catches and finally block to be distinct try

                    il.OpenLocalScope(ScopeType.TryCatchFinally);       // try {} catch (ScriptDiedException) {}
                    il.OpenLocalScope(ScopeType.Try);
                    {
                        // emit .call method;
                        if (method.HasThis)
                        {
                            throw new NotImplementedException();        // TODO: create instance of ContainingType
                        }

                        // params
                        foreach (var p in method.Parameters)
                        {
                            switch (p.Name)
                            {
                            case SpecialParameterSymbol.ContextName:
                                // <ctx>
                                il.EmitLocalLoad(ctx_loc);
                                break;

                            case SpecialParameterSymbol.LocalsName:
                                // <ctx>.Globals
                                il.EmitLocalLoad(ctx_loc);
                                il.EmitCall(this, diagnostic, ILOpCode.Call, methods.Context.Globals.Getter)
                                .Expect(p.Type);
                                break;

                            case SpecialParameterSymbol.ThisName:
                                // null
                                il.EmitNullConstant();
                                break;

                            case SpecialParameterSymbol.SelfName:
                                // default(RuntimeTypeHandle)
                                var runtimetypehandle_loc = il.LocalSlotManager.AllocateSlot(types.RuntimeTypeHandle.Symbol, LocalSlotConstraints.None);
                                il.EmitValueDefault(this, diagnostic, runtimetypehandle_loc);
                                il.LocalSlotManager.FreeSlot(runtimetypehandle_loc);
                                break;

                            default:
                                throw new ArgumentException(p.Name);
                            }
                        }

                        if (il.EmitCall(this, diagnostic, ILOpCode.Call, method).SpecialType != SpecialType.System_Void)
                        {
                            il.EmitOpCode(ILOpCode.Pop);
                        }
                    }
                    il.CloseLocalScope();  // /Try

                    il.AdjustStack(1);     // Account for exception on the stack.
                    il.OpenLocalScope(ScopeType.Catch, types.ScriptDiedException.Symbol);
                    {
                        // exitcode = <exception>.ProcessStatus(ctx)
                        il.EmitLocalLoad(ctx_loc);
                        il.EmitCall(this, diagnostic, ILOpCode.Callvirt, types.ScriptDiedException.Symbol.LookupMember <MethodSymbol>("ProcessStatus"));
                        il.EmitLocalStore(exitcode_loc);
                    }
                    il.CloseLocalScope();                    // /Catch
                    if (onUnhandledException_method != null) // only if runtime defines the method (backward compat.)
                    {
                        il.OpenLocalScope(ScopeType.Catch, types.Exception.Symbol);
                        {
                            // <ex_loc> = <stack>
                            il.EmitLocalStore(ex_loc);

                            // <ctx_loc>.OnUnhandledException( <ex_loc> ) : bool
                            il.EmitLocalLoad(ctx_loc);
                            il.EmitLocalLoad(ex_loc);
                            il.EmitCall(this, diagnostic, ILOpCode.Callvirt, onUnhandledException_method)
                            .Expect(SpecialType.System_Boolean);

                            // if ( !<bool> )
                            // {
                            var lbl_end = new object();
                            il.EmitBranch(ILOpCode.Brtrue, lbl_end);

                            // rethrow <ex_loc>;
                            il.EmitLocalLoad(ex_loc);
                            il.EmitThrow(true);

                            // }
                            il.MarkLabel(lbl_end);
                        }
                        il.CloseLocalScope(); // /Catch
                    }
                    il.CloseLocalScope();     // /TryCatch
                }
                il.CloseLocalScope();         // /Try

                il.OpenLocalScope(ScopeType.Finally);
                {
                    // ctx.Dispose
                    il.EmitLocalLoad(ctx_loc);
                    il.EmitOpCode(ILOpCode.Call, -1);
                    il.EmitToken(methods.Context.Dispose.Symbol, null, diagnostic);
                }
                il.CloseLocalScope();       // /Finally
                il.CloseLocalScope();       // /TryCatch

                // return ctx.ExitCode
                il.EmitLocalLoad(exitcode_loc);
                il.EmitRet(false);
            },
                                                          null, diagnostic, false);

            SetMethodBody(realmethod, body);

            //
            this.ScriptType.EntryPointSymbol = realmethod;
        }
예제 #12
0
        /// <summary>
        /// Create real CIL entry point, where it calls given method.
        /// </summary>
        internal void CreateEntryPoint(MethodSymbol method, DiagnosticBag diagnostic)
        {
            // "static int Main(string[] args)"
            var realmethod = new SynthesizedMethodSymbol(this.ScriptType, "Main", true, false, _compilation.CoreTypes.Int32, Accessibility.Private);

            realmethod.SetParameters(new SynthesizedParameterSymbol(realmethod, ArrayTypeSymbol.CreateSZArray(this.Compilation.SourceAssembly, this.Compilation.CoreTypes.String), 0, RefKind.None, "args"));

            //
            var body = MethodGenerator.GenerateMethodBody(this, realmethod,
                                                          (il) =>
            {
                var types      = this.Compilation.CoreTypes;
                var args_place = new ParamPlace(realmethod.Parameters[0]);

                // AddScriptReference<Script>()
                var AddScriptReferenceMethod = (MethodSymbol)this.Compilation.CoreMethods.Context.AddScriptReference_TScript.Symbol.Construct(this.ScriptType);
                il.EmitCall(this, diagnostic, ILOpCode.Call, AddScriptReferenceMethod);

                // int exitcode = 0;
                var exitcode_loc = il.LocalSlotManager.AllocateSlot(types.Int32.Symbol, LocalSlotConstraints.None);
                il.EmitIntConstant(0);
                il.EmitLocalStore(exitcode_loc);

                // create Context
                var ctx_loc = il.LocalSlotManager.AllocateSlot(types.Context.Symbol, LocalSlotConstraints.None);

                // ctx_loc = Context.Create***(args)
                args_place.EmitLoad(il);
                MethodSymbol create_method = (_compilation.Options.OutputKind == OutputKind.ConsoleApplication)
                        ? _compilation.CoreTypes.Context.Symbol.LookupMember <MethodSymbol>("CreateConsole")
                        : null;
                Debug.Assert(create_method != null);
                il.EmitOpCode(ILOpCode.Call, +1);
                il.EmitToken(create_method, null, diagnostic);
                il.EmitLocalStore(ctx_loc);

                // Template:
                // try { Main(...); } catch (ScriptDiedException) { } finally { ctx.Dispose; }

                il.OpenLocalScope(ScopeType.TryCatchFinally);       // try { try ... } finally {}
                il.OpenLocalScope(ScopeType.Try);
                {
                    // IL requires catches and finally block to be distinct try

                    il.OpenLocalScope(ScopeType.TryCatchFinally);       // try {} catch (ScriptDiedException) {}
                    il.OpenLocalScope(ScopeType.Try);
                    {
                        // emit .call method;
                        if (method.HasThis)
                        {
                            throw new NotImplementedException();        // TODO: create instance of ContainingType
                        }

                        // params
                        foreach (var p in method.Parameters)
                        {
                            if (p.Type == types.Context && p.Name == SpecialParameterSymbol.ContextName)
                            {
                                // <ctx>
                                il.EmitLocalLoad(ctx_loc);
                            }
                            else if (p.Type == types.PhpArray && p.Name == SpecialParameterSymbol.LocalsName)
                            {
                                // <ctx>.Globals
                                il.EmitLocalLoad(ctx_loc);
                                il.EmitCall(this, diagnostic, ILOpCode.Call, this.Compilation.CoreMethods.Context.get_Globals)
                                .Expect(p.Type);
                            }
                            else if (p.Type == types.Object && p.Name == SpecialParameterSymbol.ThisName)
                            {
                                // null
                                il.EmitNullConstant();
                            }
                            else
                            {
                                throw new NotImplementedException();        // TODO: default parameter
                            }
                        }

                        if (il.EmitCall(this, diagnostic, ILOpCode.Call, method).SpecialType != SpecialType.System_Void)
                        {
                            il.EmitOpCode(ILOpCode.Pop);
                        }
                    }
                    il.CloseLocalScope();  // /Try

                    il.AdjustStack(1);     // Account for exception on the stack.
                    il.OpenLocalScope(ScopeType.Catch, Compilation.CoreTypes.ScriptDiedException.Symbol);
                    {
                        // exitcode = <exception>.ProcessStatus(ctx)
                        il.EmitLocalLoad(ctx_loc);
                        il.EmitCall(this, diagnostic, ILOpCode.Callvirt, Compilation.CoreTypes.ScriptDiedException.Symbol.LookupMember <MethodSymbol>("ProcessStatus"));
                        il.EmitLocalStore(exitcode_loc);
                    }
                    il.CloseLocalScope();   // /Catch
                    il.CloseLocalScope();   // /TryCatch
                }
                il.CloseLocalScope();       // /Try

                il.OpenLocalScope(ScopeType.Finally);
                {
                    // ctx.Dispose
                    il.EmitLocalLoad(ctx_loc);
                    il.EmitOpCode(ILOpCode.Call, -1);
                    il.EmitToken(this.Compilation.CoreMethods.Context.Dispose.Symbol, null, diagnostic);
                }
                il.CloseLocalScope();       // /Finally
                il.CloseLocalScope();       // /TryCatch

                // return ctx.ExitCode
                il.EmitLocalLoad(exitcode_loc);
                il.EmitRet(false);
            },
                                                          null, diagnostic, false);

            SetMethodBody(realmethod, body);

            //
            this.ScriptType.EntryPointSymbol = realmethod;
        }