private EmitThisCall ( |
||
target | Method to be called. | |
thismethod | Current method. | |
Résultat | TypeSymbol |
/// <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.EmitThisCall(method, ghost), 0, ghost.ReturnType); cg.EmitRet(ghost.ReturnType); }, null, diagnostic, false); module.SetMethodBody(ghost, body); }
void EmitPhpCtor(MethodSymbol ctor, Emit.PEModuleBuilder module) { if (ctor == null) return; // static class Debug.Assert(ctor.MethodKind == MethodKind.Constructor); module.SetMethodBody(ctor, MethodGenerator.GenerateMethodBody(module, ctor, il => { Debug.Assert(SpecialParameterSymbol.IsContextParameter(ctor.Parameters[0])); var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, new ParamPlace(ctor.Parameters[0]), new ArgPlace(this, 0)); // call .phpnew var phpnew = this.InitializeInstanceMethod; cg.EmitPop(cg.EmitThisCall(phpnew, ctor)); // call __construct var phpctor = this.ResolvePhpCtor(true); cg.EmitPop(cg.EmitThisCall(phpctor, ctor)); Debug.Assert(ctor.ReturnsVoid); cg.EmitRet(ctor.ReturnType); }, null, DiagnosticBag.GetInstance(), false)); }
void EmitPhpNew(SynthesizedPhpNewMethodSymbol phpnew, Emit.PEModuleBuilder module) { if (phpnew == null) return; // static class module.SetMethodBody(phpnew, MethodGenerator.GenerateMethodBody(module, phpnew, (Action<Microsoft.CodeAnalysis.CodeGen.ILBuilder>)(il => { Debug.Assert(SpecialParameterSymbol.IsContextParameter(phpnew.Parameters[0])); var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, new ParamPlace(phpnew.Parameters[0]), new ArgPlace(this, 0)); // initialize <ctx> field, // if field is declared within this type var ctxField = this.ContextStore; if (ctxField != null && object.ReferenceEquals((object)ctxField.ContainingType, this)) { var ctxFieldPlace = new FieldPlace(cg.ThisPlaceOpt, (IFieldSymbol)ctxField); // Debug.Assert(<ctx> != null) cg.EmitDebugAssertNotNull(cg.ContextPlaceOpt, "Context cannot be null."); // <this>.<ctx> = <ctx> ctxFieldPlace.EmitStorePrepare(il); cg.EmitLoadContext(); ctxFieldPlace.EmitStore(il); } // initialize class fields foreach (var fld in this.GetFieldsToEmit().OfType<SourceFieldSymbol>().Where(fld => !fld.RequiresHolder && !fld.IsStatic && !fld.IsConst)) { fld.EmitInit(cg); } // base..phpnew ?? base..ctor var basenew = phpnew.BasePhpNew; Debug.Assert(basenew != null); cg.EmitPop(cg.EmitThisCall(basenew, phpnew)); Debug.Assert(phpnew.ReturnsVoid); cg.EmitRet(phpnew.ReturnType); }), null, DiagnosticBag.GetInstance(), false)); }
/// <summary> /// Generates ghost method body that calls <c>this</c> method. /// </summary> protected void GenerateGhostBody(PEModuleBuilder module, DiagnosticBag diagnostic, SynthesizedMethodSymbol ghost) { var body = MethodGenerator.GenerateMethodBody(module, ghost, (il) => { var cg = new CodeGenerator(il, module, diagnostic, OptimizationLevel.Release, false, this.ContainingType, this.GetContextPlace(), this.GetThisPlace()); // return (T){routine}(p0, ..., pN); cg.EmitConvert(cg.EmitThisCall(this, ghost), 0, ghost.ReturnType); cg.EmitRet(ghost.ReturnType); }, null, diagnostic, false); module.SetMethodBody(ghost, body); }