void EmitInit(Emit.PEModuleBuilder module) { // void Init(Context) var tt = DeclaringCompilation.CoreTypes; var diagnostic = DiagnosticBag.GetInstance(); // override IStaticInit.Init(Context) { .. } var initMethod = new SynthesizedMethodSymbol(this, "Init", false, true, tt.Void, Accessibility.Public); initMethod.SetParameters(new SynthesizedParameterSymbol(initMethod, tt.Context, 0, RefKind.None, "ctx")); var body = MethodGenerator.GenerateMethodBody(module, initMethod, (il) => { var cg = new CodeGenerator(il, module, diagnostic, OptimizationLevel.Release, false, this, new ArgPlace(tt.Context, 1), new ArgPlace(this, 0)); foreach (var fld in this.Fields) { if (fld.RequiresContext) { fld.EmitInit(cg); } } // il.EmitRet(true); }, null, diagnostic, false); module.SetMethodBody(initMethod, body); module.SynthesizedManager.AddMethod(this, initMethod); }
public void EmitCtor(Emit.PEModuleBuilder module, Action<Microsoft.CodeAnalysis.CodeGen.ILBuilder> builder) { Debug.Assert(_ctor == null); // emit default .ctor _ctor = new SynthesizedCtorSymbol(this); _ctor.SetParameters();// empty params (default ctor) var body = CodeGen.MethodGenerator.GenerateMethodBody(module, _ctor, builder, null, DiagnosticBag.GetInstance(), false); module.SetMethodBody(_ctor, body); }
internal void EmitCtors(Emit.PEModuleBuilder module) { bool requiresInit = false; // .ctor() var tt = DeclaringCompilation.CoreTypes; var diagnostic = DiagnosticBag.GetInstance(); var ctor = new SynthesizedCtorSymbol(this); var body = MethodGenerator.GenerateMethodBody(module, ctor, (il) => { var cg = new CodeGenerator(il, module, diagnostic, OptimizationLevel.Release, false, this, null, new ArgPlace(this, 0)); foreach (var fld in this.Fields) { if (fld.RequiresContext) { requiresInit = true; } else { fld.EmitInit(cg); } } // il.EmitRet(true); }, null, diagnostic, false); module.SetMethodBody(ctor, body); module.SynthesizedManager.AddMethod(this, ctor); // if (requiresInit) { EmitInit(module); } }
void EmitInvoke(MethodSymbol invoke, Emit.PEModuleBuilder module) { if (invoke == null) { return; } module.SetMethodBody(invoke, MethodGenerator.GenerateMethodBody(module, invoke, il => { var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, new ParamPlace(invoke.Parameters[0]), new ArgPlace(this, 0)); //var __invoke = (MethodSymbol)GetMembers(Pchp.Syntax.Name.SpecialMethodNames.Invoke.Value).Single(s => s is MethodSymbol); // TODO: call __invoke() directly // context.Call<T>(T, TypeMethods.MagicMethods, params PhpValue[]) var call_t = cg.CoreTypes.Context.Symbol.GetMembers("Call") .OfType<MethodSymbol>() .Where(s => s.Arity == 1 && s.ParameterCount == 3 && s.Parameters[2].IsParams) .Single() .Construct(this); // return context.Call<T>(this, __invoke, args) cg.EmitLoadContext(); cg.EmitThis(); cg.Builder.EmitIntConstant((int)Core.Reflection.TypeMethods.MagicMethods.__invoke); cg.Builder.EmitLoadArgumentOpcode(2); cg.EmitCall(ILOpCode.Call, call_t); cg.EmitRet(invoke.ReturnType); }, null, DiagnosticBag.GetInstance(), false)); }
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)); }
public void EmitInit(Emit.PEModuleBuilder module, Action<Microsoft.CodeAnalysis.CodeGen.ILBuilder> builder) { Debug.Assert(_initMethod == null); var tt = DeclaringCompilation.CoreTypes; // override IStaticInit.Init(Context) _initMethod = new SynthesizedMethodSymbol(this, "Init", false, true, tt.Void, Accessibility.Public); _initMethod.SetParameters(new SynthesizedParameterSymbol(_initMethod, tt.Context, 0, RefKind.None, "ctx")); var body = CodeGen.MethodGenerator.GenerateMethodBody(module, _initMethod, builder, null, DiagnosticBag.GetInstance(), false); module.SetMethodBody(_initMethod, body); }