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)); }
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))); }
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)); }
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)); }
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)); }
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)); }
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))))); }
/// <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)); } }
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 )); }
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; }
/// <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; }