public EmitCallMain ( |
||
mainmethod | Static Main method representing the script global code. | |
return | TypeSymbol |
internal override TypeSymbol Emit(CodeGenerator cg) { TypeSymbol result; var isvoid = this.Access.IsNone; Debug.Assert(_arguments.Length == 1); Debug.Assert(_arguments[0].Value.Access.IsRead); Debug.Assert(Access.IsRead || Access.IsNone); var method = this.Target; if (method != null) // => IsResolved { // emit condition for include_once/require_once if (IsOnceSemantic) { var tscript = method.ContainingType; result = isvoid ? cg.CoreTypes.Void.Symbol : cg.DeclaringCompilation.GetTypeFromTypeRef(cg.Routine.TypeRefContext, this.TypeRefMask); // Template: (<ctx>.CheckIncludeOnce<TScript>()) ? <Main>() : TRUE // Template<isvoid>: if (<ctx>.CheckIncludeOnce<TScript>()) <Main>() var falseLabel = new object(); var endLabel = new object(); cg.EmitLoadContext(); cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.Context.CheckIncludeOnce_TScript.Symbol.Construct(tscript)); cg.Builder.EmitBranch(ILOpCode.Brfalse, falseLabel); // ? (PhpValue)<Main>(...) cg.EmitCallMain(method); if (isvoid) { cg.EmitPop(method.ReturnType); } else { cg.EmitConvert(method.ReturnType, 0, result); } cg.Builder.EmitBranch(ILOpCode.Br, endLabel); if (!isvoid) { cg.Builder.AdjustStack(-1); // workarounds assert in ILBuilder.MarkLabel, we're doing something wrong with ILBuilder } // : PhpValue.Create(true) cg.Builder.MarkLabel(falseLabel); if (!isvoid) { cg.Builder.EmitBoolConstant(true); cg.EmitConvert(cg.CoreTypes.Boolean, 0, result); } // cg.Builder.MarkLabel(endLabel); } else { // <Main> result = cg.EmitCallMain(method); } } else { Debug.Assert(cg.LocalsPlaceOpt != null); // Template: <ctx>.Include(dir, path, locals, @this, bool once = false, bool throwOnError = false) cg.EmitLoadContext(); cg.Builder.EmitStringConstant(cg.Routine.ContainingFile.DirectoryRelativePath); cg.EmitConvert(_arguments[0].Value, cg.CoreTypes.String); cg.LocalsPlaceOpt.EmitLoad(cg.Builder); // scope of local variables, corresponds to $GLOBALS in global scope. cg.EmitThisOrNull(); // $this cg.Builder.EmitBoolConstant(IsOnceSemantic); cg.Builder.EmitBoolConstant(IsRequireSemantic); return cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.Context.Include_string_string_PhpArray_object_bool_bool); } // return result; }