コード例 #1
0
ファイル: Properties.cs プロジェクト: tiaohai/Phalanger
        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);
        }
コード例 #2
0
ファイル: CodeGenerator.cs プロジェクト: dw4dev/Phalanger
		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);
				}
			}
		}
コード例 #3
0
ファイル: Properties.cs プロジェクト: tiaohai/Phalanger
		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));
		}
コード例 #4
0
ファイル: Methods.cs プロジェクト: tiaohai/Phalanger
        /// <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&lt;T&gt;"/>.</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;
        }