Beispiel #1
0
        /// <summary>
        /// Generates ghost method body that calls <c>this</c> method.
        /// </summary>
        static void GenerateGhostBody(PEModuleBuilder module, DiagnosticBag diagnostic, MethodSymbol method, SynthesizedMethodSymbol ghost)
        {
            var containingtype = ghost.ContainingType;

            var body = MethodGenerator.GenerateMethodBody(module, ghost,
                                                          (il) =>
            {
                // $this
                var thisPlace = ghost.HasThis ? new ArgPlace(containingtype, 0) : null;

                // Context
                var ctxPlace = thisPlace != null && ghost.ContainingType is SourceTypeSymbol sourcetype
                        ? new FieldPlace(thisPlace, sourcetype.ContextStore)
                        : (IPlace) new ArgPlace(module.Compilation.CoreTypes.Context, 0);

                var cg = new CodeGenerator(il, module, diagnostic, module.Compilation.Options.OptimizationLevel, false, containingtype, ctxPlace, thisPlace);

                // return (T){routine}(p0, ..., pN);
                cg.EmitConvert(cg.EmitForwardCall(method, ghost), 0, ghost.ReturnType);
                cg.EmitRet(ghost.ReturnType);
            },
                                                          null, diagnostic, false);

            module.SetMethodBody(ghost, body);
        }
Beispiel #2
0
        /// <summary>
        /// Generates ghost method body that calls <c>this</c> method.
        /// </summary>
        static void GenerateGhostBody(PEModuleBuilder module, DiagnosticBag diagnostic, MethodSymbol method, SynthesizedMethodSymbol ghost)
        {
            var containingtype = ghost.ContainingType;

            var body = MethodGenerator.GenerateMethodBody(module, ghost,
                                                          (il) =>
            {
                // $this
                var thisPlace = ghost.HasThis ? new ArgPlace(containingtype, 0) : null;

                // Context
                var ctxPlace = thisPlace != null && ghost.ContainingType is SourceTypeSymbol sourcetype
                        ? (sourcetype.ContextStore != null ? new FieldPlace(thisPlace, sourcetype.ContextStore, module) : null)
                        : (IPlace) new ArgPlace(module.Compilation.CoreTypes.Context, 0);

                // .callvirt
                bool callvirt = ghost.ExplicitOverride != null && ghost.ExplicitOverride.ContainingType.IsInterface;      // implementing interface, otherwise we should be able to call specific method impl. non-virtually via ghost

                var cg = new CodeGenerator(il, module, diagnostic, module.Compilation.Options.OptimizationLevel, false, containingtype, ctxPlace, thisPlace)
                {
                    DebugRoutine = ghost,
                };

                // return (T){routine}(p0, ..., pN);
                cg.EmitConvert(cg.EmitForwardCall(method, ghost, callvirt: callvirt), 0, ghost.ReturnType);
                cg.EmitRet(ghost.ReturnType);
            },
                                                          null, diagnostic, false);

            module.SetMethodBody(ghost, body);
        }