internal override PhpTypeCode EmitGet(CodeGenerator /*!*/ codeGenerator, ConstructedType constructedType, bool runtimeVisibilityCheck, string fallbackName) { ILEmitter il = codeGenerator.IL; if (HasValue) { il.LoadLiteral(Value); return(PhpTypeCodeEnum.FromObject(Value)); } else { Debug.Assert(realField != null); il.Emit(OpCodes.Ldsfld, DType.MakeConstructed(realField, constructedType)); return(PhpTypeCodeEnum.FromType(realField.FieldType)); } }
/// <summary> /// Emits stub for one overridden/implemented/exported CLR overload. /// </summary> /// <param name="il"></param> /// <param name="scriptContextPlace"></param> /// <param name="stubParameters">The overload parameters.</param> /// <param name="stubTypeParameters">The overload type parameters.</param> /// <param name="stubReturnType">The overload return type.</param> /// <param name="target">The overriding/implementing/exporting method.</param> /// <param name="targetType">The type (perhaps constructed) that declared <paramref name="target"/>.</param> public static void EmitMethodStubBody(ILEmitter /*!*/ il, IPlace /*!*/ scriptContextPlace, ParameterInfo[] /*!*/ stubParameters, Type[] /*!*/ stubTypeParameters, Type /*!*/ stubReturnType, PhpMethod /*!*/ target, DType /*!*/ targetType) { bool stub_is_static = il.MethodBase.IsStatic; ClrStubBuilder stub_builder = new ClrStubBuilder(il, scriptContextPlace, stubParameters.Length, (stub_is_static ? 0 : 1)); if (stubParameters.Length >= target.Signature.MandatoryParamCount && stubTypeParameters.Length >= target.Signature.MandatoryGenericParamCount && (target.Properties & RoutineProperties.IsArgsAware) == 0) { // we can directly call the target argful if (!stub_is_static) { il.Ldarg(FunctionBuilder.ArgThis); } scriptContextPlace.EmitLoad(il); stub_builder.EmitLoadArgfullParameters(stubParameters, stubTypeParameters, target); // invoke the target (virtually if it's not static) il.Emit(stub_is_static ? OpCodes.Call : OpCodes.Callvirt, DType.MakeConstructed(target.ArgFullInfo, targetType as ConstructedType)); } else { // we have to take the argless way stub_builder.EmitLoadArglessParameters(stubParameters, stubTypeParameters, target); // invoke the target's argless // TODO: this is not behaving 100% correct, because we're losing virtual dispatch here if (stub_is_static) { il.Emit(OpCodes.Ldnull); } else { il.Ldarg(FunctionBuilder.ArgThis); } scriptContextPlace.EmitLoad(il); il.Emit(OpCodes.Ldfld, Fields.ScriptContext_Stack); il.Emit(OpCodes.Call, DType.MakeConstructed(target.ArgLessInfo, targetType as ConstructedType)); } // do not keep it on stack needlessly if (stubReturnType == Types.Void) { il.Emit(OpCodes.Pop); } // convert ref/out parameters back to CLR type for (int i = 0; i < stubParameters.Length; i++) { stub_builder.EmitStoreClrParameter(stubParameters[i]); } if (stubReturnType != Types.Void) { // convert the return parameter back to CLR type stub_builder.EmitConvertReturnValue( stubReturnType, target.Signature.AliasReturn ? PhpTypeCode.PhpReference : PhpTypeCode.Object); } il.Emit(OpCodes.Ret); }