internal static void EmitGetterStub(ILEmitter/*!*/ il, PropertyInfo/*!*/ propertyInfo, Type/*!*/ declaringType) { var getter = propertyInfo.GetGetMethod(/*false*/); if (getter == null) { il.Emit(OpCodes.Ldstr, declaringType.Name); il.Emit(OpCodes.Ldstr, "get_" + propertyInfo.Name); il.Emit(OpCodes.Call, Methods.PhpException.UndefinedMethodCalled); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ret); return; } if (getter.IsStatic) { // [ return getter() ] il.Emit(OpCodes.Call, getter); } else { // [ return ((self)<instance>).getter() ] il.Ldarg(0); il.Emit(OpCodes.Castclass, declaringType); il.Emit(OpCodes.Call, getter); } // box il.EmitBoxing(PhpTypeCodeEnum.FromType(getter.ReturnType)); // il.Emit(OpCodes.Ret); }
public void EmitConstantExportStub(ClassConstant/*!*/ constant, PropertyBuilder/*!*/ property) { Debug.Assert(constant != null && constant.IsExported && property != null); MethodBuilder getter = (MethodBuilder)property.GetGetMethod(true); // emit getter: if (getter != null) { EmissionContext emission_context = SetupStubPlaces(constant.DeclaringPhpType, getter.IsStatic); il = new ILEmitter(getter); try { // read the field PhpTypeCode type_code = constant.EmitGet(this, null, false, null); // convert it to the return type //ClrOverloadBuilder.EmitConvertToClr( // il, // type_code, // getter.ReturnType); il.EmitBoxing(type_code); il.Emit(OpCodes.Ret); } finally { RestorePlaces(emission_context); } } }
protected virtual GetterDelegate/*!*/ GenerateGetterStub() { #if SILVERLIGHT DynamicMethod stub = new DynamicMethod("<^GetterStub>", Types.Object[0], Types.Object); #else DynamicMethod stub = new DynamicMethod("<^GetterStub>", PhpFunctionUtils.DynamicStubAttributes, CallingConventions.Standard, Types.Object[0], Types.Object, this.declaringType.RealType, true); #endif ILEmitter il = new ILEmitter(stub); ClrEvent clr_event; ClrProperty clr_property; Type result_type; if ((clr_event = Member as ClrEvent) != null) { Debug.Assert(!declaringType.RealType.IsValueType, "Value type with ClrEvent not handled! TODO: arg(0) is ClrValue<T>."); LocalBuilder temp = il.DeclareLocal(declaringType.RealType); il.Ldarg(0); il.Emit(OpCodes.Castclass, declaringType.RealType); il.Stloc(temp); clr_event.EmitGetEventObject(il, new Place(null, Properties.ScriptContext_CurrentContext), new Place(temp), true); } else { if ((clr_property = Member as ClrProperty) != null) { // return error-throwing getter if the property is write-only if (!clr_property.HasGetter) return new GetterDelegate(MissingGetter); if (!clr_property.Getter.IsStatic) { ClrOverloadBuilder.EmitLoadInstance(il, IndexedPlace.ThisArg, declaringType.RealType); // il.Emit(OpCodes.Ldarg_0); // if (declaringType.RealType.IsValueType) // il.Emit(OpCodes.Unbox, declaringType.RealType); //#if EMIT_VERIFIABLE_STUBS // else // il.Emit(OpCodes.Castclass, this.declaringType.RealType); //#endif } il.Emit(OpCodes.Call, clr_property.Getter); result_type = clr_property.Getter.ReturnType; } else { ClrField clr_field = ClrField; if (!clr_field.FieldInfo.IsStatic) { ClrOverloadBuilder.EmitLoadInstance(il, IndexedPlace.ThisArg, declaringType.RealType); //il.Emit(OpCodes.Ldarg_0); ////il.Emit(OpCodes.Castclass, this.declaringType.RealType); //if (declaringType.RealType.IsValueType) il.Emit(OpCodes.Unbox, declaringType.RealType); il.Emit(OpCodes.Ldfld, clr_field.FieldInfo); } else { il.Emit(OpCodes.Ldsfld, clr_field.FieldInfo); } result_type = clr_field.FieldInfo.FieldType; } il.EmitBoxing(ClrOverloadBuilder.EmitConvertToPhp(il, result_type/*, null*/)); } il.Emit(OpCodes.Ret); return (GetterDelegate)stub.CreateDelegate(typeof(GetterDelegate)); }
/// <summary> /// Emit static method that creates an instance of given value type using default ctor. /// </summary> /// <param name="valueType">Value type to be instantiated by resulting method.</param> /// <returns>The method that returns value boxed into new instance of <see cref="ClrValue<T>"/>.</returns> private static MethodBase BuildDefaultValueCtor(Type/*!*/valueType) { Debug.Assert(valueType != null && valueType.IsValueType, "Argument 'valueType' must not be null and must represent a value type!"); DynamicMethod method = new DynamicMethod(valueType.Name + "..ctor", Types.Object[0], Type.EmptyTypes); Emit.ILEmitter il = new PHP.Core.Emit.ILEmitter(method); // local 0 // ldloca.s 0 // initobj <valueType> var loc = il.DeclareLocal(valueType); il.Emit(OpCodes.Ldloca_S, loc); il.Emit(OpCodes.Initobj, valueType); // LOAD <loc> // box ConvertToPhp <valueType> il.Emit(OpCodes.Ldloc, loc); il.EmitBoxing(ClrOverloadBuilder.EmitConvertToPhp(il, valueType)); // return il.Emit(OpCodes.Ret); // done return method; }