public Scope(CodeGenerator generator, ILBuilder il, bool isFunction, BoundBody body, BoundClosureField argumentsClosureField, ITypeBuilder typeBuilder, Scope parent)
            {
                IL = il;
                ArgumentsClosureField = argumentsClosureField;
                Generator = generator;
                _isFunction = isFunction;
                _body = body;
                if (argumentsClosureField != null)
                    ArgumentsEmitter = new ClosureFieldEmitter(generator, argumentsClosureField);
                TypeBuilder = typeBuilder;
                Parent = parent;

                _isStatic = TypeBuilder is IScriptBuilder;
                if (body.MappedArguments != null)
                    _arguments = body.MappedArguments.ToDictionary(p => p.Argument, p => p.Mapped);

                BreakTargets = new Stack<NamedLabel>();
                ContinueTargets = new Stack<NamedLabel>();
            }
Exemple #2
0
 protected override void Operation(ILBuilder il)
 {
     il.Math.And();
 }
Exemple #3
0
        public CodeGenerator(
            MethodSymbol method,
            BoundStatement boundBody,
            ILBuilder builder,
            PEModuleBuilder moduleBuilder,
            DiagnosticBag diagnostics,
            OptimizationLevel optimizations,
            bool emittingPdb)
        {
            Debug.Assert((object)method != null);
            Debug.Assert(boundBody != null);
            Debug.Assert(builder != null);
            Debug.Assert(moduleBuilder != null);
            Debug.Assert(diagnostics != null);

            _method      = method;
            _boundBody   = boundBody;
            _builder     = builder;
            _module      = moduleBuilder;
            _diagnostics = diagnostics;

            if (!method.GenerateDebugInfo)
            {
                // Always optimize synthesized methods that don't contain user code.
                //
                // Specifically, always optimize synthesized explicit interface implementation methods
                // (aka bridge methods) with by-ref returns because peverify produces errors if we
                // return a ref local (which the return local will be in such cases).
                _ilEmitStyle = ILEmitStyle.Release;
            }
            else
            {
                if (optimizations == OptimizationLevel.Debug)
                {
                    _ilEmitStyle = ILEmitStyle.Debug;
                }
                else
                {
                    _ilEmitStyle = IsDebugPlus() ?
                                   ILEmitStyle.DebugFriendlyRelease :
                                   ILEmitStyle.Release;
                }
            }

            // Emit sequence points unless
            // - the PDBs are not being generated
            // - debug information for the method is not generated since the method does not contain
            //   user code that can be stepped through, or changed during EnC.
            //
            // This setting only affects generating PDB sequence points, it shall not affect generated IL in any way.
            _emitPdbSequencePoints = emittingPdb && method.GenerateDebugInfo;

            try
            {
                _boundBody = Optimizer.Optimize(
                    boundBody,
                    debugFriendly: _ilEmitStyle != ILEmitStyle.Release,
                    stackLocals: out _stackLocals);
            }
            catch (BoundTreeVisitor.CancelledByStackGuardException ex)
            {
                ex.AddAnError(diagnostics);
                _boundBody = boundBody;
            }

            var sourceMethod = method as SourceMemberMethodSymbol;

            (BlockSyntax blockBody, ArrowExpressionClauseSyntax expressionBody) = sourceMethod?.Bodies ?? default;
            _methodBodySyntaxOpt = (SyntaxNode)blockBody ?? expressionBody ?? sourceMethod?.SyntaxNode;
        }
 internal void SetMethodTestData(IMethodSymbol method, ILBuilder builder)
 {
     TestData.Add(method, new CompilationTestData.MethodData(builder, method));
 }
Exemple #5
0
        internal override IPlace Place(ILBuilder il)
        {
            // TODO: place of superglobal variable

            return(null);
        }
Exemple #6
0
 internal override IBoundReference BindPlace(ILBuilder il, BoundAccess access, TypeRefMask thint)
 {
     return(new BoundLocalPlace(Place(il), access, thint));
 }
Exemple #7
0
 /// <summary>
 /// Gets <see cref="IBoundReference"/> providing load and store operations.
 /// </summary>
 internal abstract IBoundReference BindPlace(ILBuilder il, BoundAccess access, TypeRefMask thint);
Exemple #8
0
 internal override IBoundReference BindPlace(ILBuilder il, BoundAccess access, TypeRefMask thint)
 {
     return(new BoundIndirectVariablePlace(_nameExpr, access));
 }
Exemple #9
0
 internal override IPlace Place(ILBuilder il) => _place;
Exemple #10
0
        public override void Generate(ILBuilder il, ICompiler compiler)
        {
            using (var objNum = il.NewLocal <ushort>())
            {
                // Read objNum
                var done = il.NewLabel();
                compiler.EmitLoadValidObject(objectOp, done, reuse: ReuseFirstOperand);
                objNum.Store();

                using (var propNum = il.NewLocal <ushort>())
                    using (var value = il.NewLocal <byte>())
                        using (var propAddress = il.NewLocal <ushort>())
                        {
                            // Read propNum
                            compiler.EmitLoadOperand(propertyOp);
                            propNum.Store();

                            il.DebugWrite("propNum: {0}", propNum);

                            int mask = compiler.Version < 4 ? 0x1f : 0x3f;

                            // Read first property address into propAddress
                            compiler.EmitLoadFirstPropertyAddress(objNum);
                            propAddress.Store();

                            var loopStart = il.NewLabel();
                            var loopDone  = il.NewLabel();

                            il.DebugIndent();
                            loopStart.Mark();

                            // Read first property byte and store in value
                            compiler.EmitLoadMemoryByte(propAddress);
                            value.Store();

                            // if ((value & mask) <= propNum) break;
                            value.Load();
                            il.Math.And(mask);

#if DEBUG
                            using (var temp = il.NewLocal <ushort>())
                            {
                                temp.Store();
                                il.DebugWrite("property number at address: {0} {1:x4}", temp, propAddress);
                                temp.Load();
                            }
#endif

                            propNum.Load();
                            loopDone.BranchIf(Condition.AtMost, @short: true);

                            // Read next property address into propAddress
                            propAddress.Load();
                            compiler.EmitLoadNextPropertyAddress();
                            propAddress.Store();

                            // Branch to start of loop
                            loopStart.Branch();

                            loopDone.Mark();
                            il.DebugUnindent();

                            // if ((value & mask) != propNum) throw;
                            var propNumFound = il.NewLabel();
                            value.Load();
                            il.Math.And(mask);
                            propNum.Load();
                            propNumFound.BranchIf(Condition.Equal, @short: true);
                            il.RuntimeError("Object {0} does not contain property {1}", objNum, propNum);

                            propNumFound.Mark();

                            il.DebugWrite("Found property {0} at address {1:x4}", propNum, propAddress);

                            // propAddress++;
                            propAddress.Load();
                            il.Math.Add(1);
                            il.Convert.ToUInt16();
                            propAddress.Store();

                            var sizeIsWord = il.NewLabel();

                            // if ((this.version <= 3 && (value & 0xe0) != 0) && (this.version >= 4) && (value & 0xc0) != 0)
                            int sizeMask = compiler.Version < 4 ? 0xe0 : 0xc0;
                            value.Load();
                            il.Math.And(sizeMask);
                            sizeIsWord.BranchIf(Condition.True, @short: true);

                            // write byte
                            using (var temp = il.NewLocal <byte>())
                            {
                                compiler.EmitLoadOperand(valueOp);
                                il.Convert.ToUInt8();
                                temp.Store();

                                compiler.EmitStoreMemoryByte(propAddress, temp);

                                il.DebugWrite("Wrote byte {0:x2} to {1:x4}", temp, propAddress);

                                done.Branch(@short: true);
                            }

                            // write word
                            sizeIsWord.Mark();

                            using (var temp = il.NewLocal <ushort>())
                            {
                                compiler.EmitLoadOperand(valueOp);
                                temp.Store();

                                compiler.EmitStoreMemoryWord(propAddress, temp);

                                il.DebugWrite("Wrote word {0:x2} to {1:x4}", temp, propAddress);
                            }
                        }

                done.Mark();
            }
        }
Exemple #11
0
 internal override IBoundReference BindPlace(ILBuilder il, BoundAccess access, TypeRefMask thint)
 {
     return(new BoundThisPlace(_routine, access));
 }
Exemple #12
0
 protected override void Operation(ILBuilder il)
 {
     il.Math.Remainder();
 }
Exemple #13
0
 public void EmitStore(ILBuilder il) => il.EmitLocalStore(_def);
Exemple #14
0
 public void EmitStorePrepare(ILBuilder il)
 {
 }
Exemple #15
0
 public void EmitLoadAddress(ILBuilder il) => il.EmitLocalAddress(_def);
Exemple #16
0
 private IPlace LocalPlace(ILBuilder il) => _place;
Exemple #17
0
 internal override IBoundReference BindPlace(ILBuilder il, BoundAccess access, TypeRefMask thint)
 {
     return(new BoundLocalPlace(Place(il), access, _routine.TypeRefContext.GetThisTypeMask()));
 }
Exemple #18
0
 internal override IPlace Place(ILBuilder il) => null;
Exemple #19
0
 public HelperEmitter(AssemblyBuilder assemblyBuilder)
 {
     m_assemblyBuilder = assemblyBuilder;
     m_ilBuilder       = new ILBuilder(assemblyBuilder.metadataContext.ilTokenProvider);
 }
Exemple #20
0
 /// <summary>
 /// Gets <see cref="IPlace"/> of the variable.
 /// </summary>
 internal abstract IPlace Place(ILBuilder il);
Exemple #21
0
        internal static MethodBody CreateSynthesizedBody(PEModuleBuilder moduleBuilder, IMethodSymbol routine, ILBuilder il)
        {
            var compilation      = moduleBuilder.Compilation;
            var localSlotManager = il.LocalSlotManager;
            var optimizations    = compilation.Options.OptimizationLevel;

            try
            {
                il.Realize();

                //
                var localVariables = il.LocalSlotManager.LocalsInOrder();

                if (localVariables.Length > 0xFFFE)
                {
                    //diagnosticsForThisMethod.Add(ErrorCode.ERR_TooManyLocals, method.Locations.First());
                }

                //if (diagnosticsForThisMethod.HasAnyErrors())
                //{
                //    // we are done here. Since there were errors we should not emit anything.
                //    return null;
                //}

                //// We will only save the IL builders when running tests.
                //if (moduleBuilder.SaveTestData)
                //{
                //    moduleBuilder.SetMethodTestData(method, builder.GetSnapshot());
                //}

                // Only compiler-generated MoveNext methods have iterator scopes.  See if this is one.
                var stateMachineHoistedLocalScopes = default(ImmutableArray <StateMachineHoistedLocalScope>);
                //if (isStateMachineMoveNextMethod)
                //{
                //    stateMachineHoistedLocalScopes = builder.GetHoistedLocalScopes();
                //}

                var stateMachineHoistedLocalSlots = default(ImmutableArray <EncHoistedLocalInfo>);
                var stateMachineAwaiterSlots      = default(ImmutableArray <Cci.ITypeReference>);
                //if (optimizations == OptimizationLevel.Debug && stateMachineTypeOpt != null)
                //{
                //    Debug.Assert(method.IsAsync || method.IsIterator);
                //    GetStateMachineSlotDebugInfo(moduleBuilder, moduleBuilder.GetSynthesizedFields(stateMachineTypeOpt), variableSlotAllocatorOpt, diagnosticsForThisMethod, out stateMachineHoistedLocalSlots, out stateMachineAwaiterSlots);
                //    Debug.Assert(!diagnostics.HasAnyErrors());
                //}

                return(new MethodBody(
                           il.RealizedIL,
                           il.MaxStack,
                           (Cci.IMethodDefinition)routine,
                           new DebugId(0, moduleBuilder.CurrentGenerationOrdinal),
                           localVariables,
                           il.RealizedSequencePoints,
                           null,
                           il.RealizedExceptionHandlers,
                           il.AreLocalsZeroed,
                           hasStackalloc: false, // No support for stackalloc in PHP
                           il.GetAllScopes(),
                           il.HasDynamicLocal,
                           null,                                     // importScopeOpt,
                           ImmutableArray <LambdaDebugInfo> .Empty,  // lambdaDebugInfo,
                           ImmutableArray <ClosureDebugInfo> .Empty, // closureDebugInfo,
                           null,                                     //stateMachineTypeOpt?.Name,
                           stateMachineHoistedLocalScopes,
                           stateMachineHoistedLocalSlots,
                           stateMachineAwaiterSlots,
                           null,   // stateMachineMoveNextDebugInfoOpt
                           null)); // dynamicAnalysisDataOpt
            }
            finally
            {
                // Basic blocks contain poolable builders for IL and sequence points. Free those back
                // to their pools.
                il.FreeBasicBlocks();

                //// Remember diagnostics.
                //diagnostics.AddRange(diagnosticsForThisMethod);
                //diagnosticsForThisMethod.Free();
            }
        }
Exemple #22
0
        internal override IBoundReference BindPlace(ILBuilder il, BoundAccess access, TypeRefMask thint)
        {
            Debug.Assert(_name.IsAutoGlobal);

            return(new BoundSuperglobalPlace(_name, access));
        }
Exemple #23
0
 protected abstract void Operation(ILBuilder il);
Exemple #24
0
 internal override IPlace Place(ILBuilder il) => LocalPlace(il);
Exemple #25
0
 protected virtual void PostOperation(ILocal result, ILBuilder il, ICompiler compiler)
 {
 }
Exemple #26
0
        private HomeItemViewModel Parse(string source, long timer, bool generateAssembly = false)
        {
            string error = null;

            var vm = new HomeItemViewModel {
                Source = source, Timer = timer
            };
            var input = InputModule.create(vm.Source);

            var tokensResult = Lexer.tokenize(input);

            if (tokensResult.IsError)
            {
                error = tokensResult.ErrorValue;
                goto End;
            }

            var tokens = tokensResult.ResultValue;

            var programResult = Parser.parse(tokens);

            if (programResult.IsError)
            {
                error = programResult.ErrorValue;
                goto End;
            }

            var program = programResult.ResultValue;

            vm.Ast = JsonConvert.SerializeObject(_astBuilder.Build(program));

            var symbolTableResult = SymbolCollector.create(program);

            if (symbolTableResult.IsError)
            {
                error = symbolTableResult.ErrorValue;
                goto End;
            }

            var symbolTable = symbolTableResult.ResultValue;

            var typeCheckerResult = TypeChecker.check(symbolTable, program);

            if (typeCheckerResult.IsError)
            {
                error = typeCheckerResult.ErrorValue;
                goto End;
            }

            var variableInitializationCheckerResult = VariableInitializationChecker.check(program);

            if (variableInitializationCheckerResult.IsError)
            {
                error = variableInitializationCheckerResult.ErrorValue;
                goto End;
            }

            var writeLineFunc = FuncConvert.ToFSharpFunc <int>(i => vm.PrintfnLog += i + "\n");
            var environment   = EnvironmentModule.create(symbolTable, program, writeLineFunc, vm.Timer);

            var interpreterResult = Interpreter.interpret(environment);

            if (interpreterResult.IsError)
            {
                error = interpreterResult.ErrorValue;
                goto End;
            }

            var assemblyResult = ILBuilder.build(symbolTable, program);

            if (assemblyResult.IsError)
            {
                error = assemblyResult.ErrorValue;
                goto End;
            }

            var assembly = assemblyResult.ResultValue;

            vm.Il = JsonConvert.SerializeObject(_ilBuilder.Build(assembly));

            if (generateAssembly)
            {
                var applicationResult = CodeGenerator.generate(assembly);
                if (applicationResult.IsError)
                {
                    error = applicationResult.ErrorValue;
                    goto End;
                }

                vm.Application = applicationResult.ResultValue;
            }

End:
            if (error != null)
            {
                vm.Error = error;
            }

            return(vm);
        }
Exemple #27
0
        internal static MethodBody GenerateMethodBody(TypeCompilationState compilationState, MethodSymbol method, BoundStatement block, DiagnosticBag diagnostics,
                                                      bool optimize, DebugDocumentProvider debugDocumentProvider, ImmutableArray <NamespaceScope> namespaceScopes)
        {
            // Note: don't call diagnostics.HasAnyErrors() in release; could be expensive if compilation has many warnings.
            Debug.Assert(!diagnostics.HasAnyErrors(), "Running code generator when errors exist might be dangerous; code generator not well hardened");

            bool emitSequencePoints = !namespaceScopes.IsDefault && !method.IsAsync;
            var  module             = compilationState.ModuleBuilder;
            var  compilation        = module.Compilation;
            var  localSlotManager   = module.CreateLocalSlotManager(method);

            ILBuilder     builder = new ILBuilder(module, localSlotManager, optimize);
            DiagnosticBag diagnosticsForThisMethod = DiagnosticBag.GetInstance();

            try
            {
                AsyncMethodBodyDebugInfo asyncDebugInfo = null;
                if ((object)method.AsyncKickoffMethod == null) // is this the MoveNext of an async method?
                {
                    CodeGen.CodeGenerator.Run(
                        method, block, builder, module, diagnosticsForThisMethod, optimize, emitSequencePoints);
                }
                else
                {
                    int asyncCatchHandlerOffset;
                    ImmutableArray <int> asyncYieldPoints;
                    ImmutableArray <int> asyncResumePoints;
                    CodeGen.CodeGenerator.Run(
                        method, block, builder, module, diagnosticsForThisMethod, optimize, emitSequencePoints,
                        out asyncCatchHandlerOffset, out asyncYieldPoints, out asyncResumePoints);
                    asyncDebugInfo = new AsyncMethodBodyDebugInfo(method.AsyncKickoffMethod, asyncCatchHandlerOffset, asyncYieldPoints, asyncResumePoints);
                }

                var localVariables = builder.LocalSlotManager.LocalsInOrder();

                if (localVariables.Length > 0xFFFE)
                {
                    diagnosticsForThisMethod.Add(ErrorCode.ERR_TooManyLocals, method.Locations.First());
                }

                if (diagnosticsForThisMethod.HasAnyErrors())
                {
                    // we are done here. Since there were errors we should not emit anything.
                    return(null);
                }

                // We will only save the IL builders when running tests.
                if (module.SaveTestData)
                {
                    module.SetMethodTestData(method, builder.GetSnapshot());
                }

                // Only compiler-generated MoveNext methods have iterator scopes.  See if this is one.
                bool hasIteratorScopes =
                    method.Locations.IsEmpty && method.Name == "MoveNext" &&
                    (method.ExplicitInterfaceImplementations.Contains(compilation.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerator__MoveNext) as MethodSymbol) ||
                     method.ExplicitInterfaceImplementations.Contains(compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_IAsyncStateMachine_MoveNext) as MethodSymbol));

                var iteratorScopes = hasIteratorScopes ? builder.GetIteratorScopes() : ImmutableArray <LocalScope> .Empty;

                var iteratorOrAsyncImplementation = compilationState.GetIteratorOrAsyncImplementationClass(method);
                return(new MethodBody(
                           builder.RealizedIL,
                           builder.MaxStack,
                           method,
                           localVariables,
                           builder.RealizedSequencePoints,
                           debugDocumentProvider,
                           builder.RealizedExceptionHandlers,
                           builder.GetAllScopes(),
                           Microsoft.Cci.CustomDebugInfoKind.CSharpStyle,
                           builder.HasDynamicLocal,
                           namespaceScopes,
                           (object)iteratorOrAsyncImplementation == null ? null : iteratorOrAsyncImplementation.MetadataName,
                           iteratorScopes,
                           asyncMethodDebugInfo: asyncDebugInfo
                           ));
            }
            finally
            {
                // Basic blocks contain poolable builders for IL and sequence points. Free those back
                // to their pools.
                builder.FreeBasicBlocks();

                // Remember diagnostics.
                diagnostics.AddRange(diagnosticsForThisMethod);
                diagnosticsForThisMethod.Free();
            }
        }
Exemple #28
0
        private static ImmutableArray <ILVisualizer.LocalInfo> ToLocalDefinitions(ImmutableArray <LocalInfo <TypeSymbol> > localInfos, ILBuilder builder)
        {
            if (localInfos.IsEmpty)
            {
                return(ImmutableArray.Create <ILVisualizer.LocalInfo>());
            }

            var result = new ILVisualizer.LocalInfo[localInfos.Length];

            for (int i = 0; i < result.Length; i++)
            {
                var typeRef      = localInfos[i].Type;
                var builderLocal = builder.LocalSlotManager.LocalsInOrder()[i];
                result[i] = new ILVisualizer.LocalInfo(builderLocal.Name, typeRef, localInfos[i].IsPinned, localInfos[i].IsByRef);
            }

            return(result.AsImmutableOrNull());
        }
Exemple #29
0
        public static TypeSymbol EmitConvertToPhpValue(TypeSymbol from, TypeRefMask fromHint, ILBuilder il, Emit.PEModuleBuilder module, DiagnosticBag diagnostic)
        {
            Contract.ThrowIfNull(from);

            var compilation = module.Compilation;

            switch (from.SpecialType)
            {
            case SpecialType.System_Boolean:
                il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_Boolean);
                break;

            case SpecialType.System_Int32:
                il.EmitOpCode(ILOpCode.Conv_i8);       // Int32 -> Int64
                goto case SpecialType.System_Int64;    // PhpValue.Create((long)<stack>)

            case SpecialType.System_Int64:
                il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_Long);
                break;

            case SpecialType.System_Double:
                il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_Double);
                break;

            case SpecialType.System_Void:
                Emit_PhpValue_Void(il, module, diagnostic);
                break;

            default:
                if (from == compilation.CoreTypes.PhpAlias)
                {
                    il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_PhpAlias)
                    .Expect(compilation.CoreTypes.PhpValue);
                    break;
                }
                else if (from == compilation.CoreTypes.PhpValue)
                {
                    // nop
                    break;
                }
                else if (from == compilation.CoreTypes.String)
                {
                    il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_String)
                    .Expect(compilation.CoreTypes.PhpValue);
                    break;
                }
                else if (from == compilation.CoreTypes.PhpString)
                {
                    il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_PhpString)
                    .Expect(compilation.CoreTypes.PhpValue);
                    break;
                }
                else if (from == compilation.CoreTypes.PhpNumber)
                {
                    il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_PhpNumber)
                    .Expect(compilation.CoreTypes.PhpValue);
                    break;
                }
                else if (from.IsOfType(compilation.CoreTypes.PhpArray))
                {
                    il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_PhpArray)
                    .Expect(compilation.CoreTypes.PhpValue);
                    break;
                }
                else if (from == compilation.CoreTypes.IntStringKey)
                {
                    il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_IntStringKey)
                    .Expect(compilation.CoreTypes.PhpValue);
                    break;
                }
                else if (from.IsReferenceType)
                {
                    il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.FromClass_Object)
                    .Expect(compilation.CoreTypes.PhpValue);
                    break;
                }
                else
                {
                    throw new NotImplementedException($"{from.Name}");
                }
            }

            //
            return(compilation.CoreTypes.PhpValue);
        }
        /// <summary>
        /// Generates method body that calls another method.
        /// Used for wrapping a method call into a method, e.g. an entry point.
        /// </summary>
        internal static MethodBody GenerateMethodBody(
            PEModuleBuilder moduleBuilder,
            MethodSymbol routine,
            Action <ILBuilder> builder,
            VariableSlotAllocator variableSlotAllocatorOpt,
            DiagnosticBag diagnostics,
            bool emittingPdb)
        {
            var compilation      = moduleBuilder.Compilation;
            var localSlotManager = new LocalSlotManager(variableSlotAllocatorOpt);
            var optimizations    = compilation.Options.OptimizationLevel;

            DebugDocumentProvider debugDocumentProvider = null;

            if (emittingPdb)
            {
                debugDocumentProvider = (path, basePath) => moduleBuilder.GetOrAddDebugDocument(path, basePath, CreateDebugDocumentForFile);
            }

            ILBuilder il = new ILBuilder(moduleBuilder, localSlotManager, optimizations);

            try
            {
                Cci.AsyncMethodBodyDebugInfo asyncDebugInfo = null;

                builder(il);

                //
                il.Realize();

                //
                var localVariables = il.LocalSlotManager.LocalsInOrder();

                if (localVariables.Length > 0xFFFE)
                {
                    //diagnosticsForThisMethod.Add(ErrorCode.ERR_TooManyLocals, method.Locations.First());
                }

                //if (diagnosticsForThisMethod.HasAnyErrors())
                //{
                //    // we are done here. Since there were errors we should not emit anything.
                //    return null;
                //}

                //// We will only save the IL builders when running tests.
                //if (moduleBuilder.SaveTestData)
                //{
                //    moduleBuilder.SetMethodTestData(method, builder.GetSnapshot());
                //}

                // Only compiler-generated MoveNext methods have iterator scopes.  See if this is one.
                var stateMachineHoistedLocalScopes = default(ImmutableArray <Cci.StateMachineHoistedLocalScope>);
                //if (isStateMachineMoveNextMethod)
                //{
                //    stateMachineHoistedLocalScopes = builder.GetHoistedLocalScopes();
                //}

                var stateMachineHoistedLocalSlots = default(ImmutableArray <EncHoistedLocalInfo>);
                var stateMachineAwaiterSlots      = default(ImmutableArray <Cci.ITypeReference>);
                //if (optimizations == OptimizationLevel.Debug && stateMachineTypeOpt != null)
                //{
                //    Debug.Assert(method.IsAsync || method.IsIterator);
                //    GetStateMachineSlotDebugInfo(moduleBuilder, moduleBuilder.GetSynthesizedFields(stateMachineTypeOpt), variableSlotAllocatorOpt, diagnosticsForThisMethod, out stateMachineHoistedLocalSlots, out stateMachineAwaiterSlots);
                //    Debug.Assert(!diagnostics.HasAnyErrors());
                //}

                return(new MethodBody(
                           il.RealizedIL,
                           il.MaxStack,
                           (Cci.IMethodDefinition)routine.PartialDefinitionPart ?? routine,
                           variableSlotAllocatorOpt?.MethodId ?? new DebugId(0, moduleBuilder.CurrentGenerationOrdinal),
                           localVariables,
                           il.RealizedSequencePoints,
                           debugDocumentProvider,
                           il.RealizedExceptionHandlers,
                           il.GetAllScopes(),
                           il.HasDynamicLocal,
                           null,                                     // importScopeOpt,
                           ImmutableArray <LambdaDebugInfo> .Empty,  // lambdaDebugInfo,
                           ImmutableArray <ClosureDebugInfo> .Empty, // closureDebugInfo,
                           null,                                     //stateMachineTypeOpt?.Name,
                           stateMachineHoistedLocalScopes,
                           stateMachineHoistedLocalSlots,
                           stateMachineAwaiterSlots,
                           asyncDebugInfo));
            }
            finally
            {
                // Basic blocks contain poolable builders for IL and sequence points. Free those back
                // to their pools.
                il.FreeBasicBlocks();

                //// Remember diagnostics.
                //diagnostics.AddRange(diagnosticsForThisMethod);
                //diagnosticsForThisMethod.Free();
            }
        }
Exemple #31
0
 public TypeSymbol EmitLoad(ILBuilder il)
 {
     il.EmitLocalLoad(_def);
     return((TypeSymbol)_def.Type);
 }