/// <summary> /// Emits call to <see cref="ScriptContext.DeclareFunction"/>. /// </summary> internal static void EmitDeclareFunction(ILEmitter/*!*/il, IPlace/*!*/scriptContextPlace, PhpFunction/*!*/ function) { Label lbl_fieldinitialized = il.DefineLabel(); // private static PhpRoutine <routine>'function = null; var attrs = FieldAttributes.Static | FieldAttributes.Private; var field = il.TypeBuilder.DefineField(string.Format("<routine>'{0}", function.FullName), typeof(PhpRoutineDesc), attrs); // if (<field> == null) il.Emit(OpCodes.Ldsfld, field); il.Emit(OpCodes.Brtrue, lbl_fieldinitialized); { // <field> = new PhpRoutineDesc(<attributes>, new RoutineDelegate(null, <delegate>)) // LOAD <attributes>; il.LdcI4((int)function.MemberDesc.MemberAttributes); // new RoutineDelegate(null, <delegate>, true) il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ldftn, function.ArgLessInfo); il.Emit(OpCodes.Newobj, Constructors.RoutineDelegate); il.LoadBool(true); // new PhpRoutineDesc: il.Emit(OpCodes.Newobj, Constructors.PhpRoutineDesc_Attr_Delegate_Bool); // <field> = <STACK> il.Emit(OpCodes.Stsfld, field); // new PurePhpFunction(<field>, fullName, argfull); // writes desc.Member il.Emit(OpCodes.Ldsfld, field); il.Emit(OpCodes.Ldstr, function.FullName); CodeGenerator.EmitLoadMethodInfo(il, function.ArgFullInfo/*, AssemblyBuilder.DelegateBuilder*/); il.Emit(OpCodes.Newobj, Constructors.PurePhpFunction); il.Emit(OpCodes.Pop); } il.MarkLabel(lbl_fieldinitialized); // CALL ScriptContent.DeclareFunction(<field>, <name>); scriptContextPlace.EmitLoad(il); // LOAD <field> il.Emit(OpCodes.Ldsfld, field); // LOAD <fullName> il.Emit(OpCodes.Ldstr, function.FullName); // il.Emit(OpCodes.Call, Methods.ScriptContext.DeclareFunction); }
/// <summary> /// Emits load of default value assuming given method fails. /// </summary> /// <param name="il">ILEmitter.</param> /// <param name="method">Method which default return value have to be loaded.</param> /// <returns></returns> public static PhpTypeCode EmitLoadDefault(ILEmitter/*!*/il, MethodInfo/*!*/method) { if (method.ReturnType == Types.Bool[0] || method.ReturnTypeCustomAttributes.IsDefined(typeof(CastToFalseAttribute), false)) { il.LoadBool(false); return PhpTypeCode.Boolean; } if (method.ReturnType == Types.Int[0]) { il.LdcI4(0); return PhpTypeCode.Integer; } return PhpTypeCode.Void; }