예제 #1
0
		internal override AssignmentCallback EmitSet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool isRef,
			ConstructedType constructedType, bool runtimeVisibilityCheck)
		{
			return codeGenerator.EmitSetStaticPropertyOperator(declaringType, this.FullName, null, isRef);
		}
예제 #2
0
		internal override AssignmentCallback EmitSet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool isRef,
			ConstructedType constructedType, bool runtimeVisibilityCheck)
		{
			Debug.Assert(IsStatic == (instance == null));

			//Debug.Assert(hasSetter, "TODO");
            if (!hasSetter)
            {
                throw new CompilerException(
                    new ErrorInfo(
                           0,
                           "readonly_property_written",
                           ErrorSeverity.Error),
                    new string[]{DeclaringType.FullName, this.Name.Value}
                    );
            }

            //
            
			if (IsStatic)
			{
				// check the visibility at runtime by the operator:
				if (runtimeVisibilityCheck)
					return codeGenerator.EmitSetStaticPropertyOperator(DeclaringType, this.FullName, null, isRef);
			}
			else
			{
				// load target instance:
				instance.EmitLoad(codeGenerator.IL);
			}

			return delegate(CodeGenerator codeGen, PhpTypeCode stackTypeCode)
			{
				MethodInfo setter = this.Setter;

				// TODO: can we get different PhpTypeCode?
				ILEmitter il = codeGen.IL;
				PropertyDesc.EmitSetConversion(il, stackTypeCode, setter.GetParameters()[0].ParameterType);

				il.Emit(setter.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, setter);
			};
		}
예제 #3
0
		internal override AssignmentCallback EmitSet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool isRef,
			ConstructedType constructedType, bool runtimeVisibilityCheck)
		{
			Debug.Assert(IsStatic == (instance == null));

			if (IsStatic)
			{
				// check the visibility at runtime by the operator:
				if (runtimeVisibilityCheck)
					return codeGenerator.EmitSetStaticPropertyOperator(DeclaringType, this.FullName, null, isRef);
			}
			else
			{
				// load target instance:
				instance.EmitLoad(codeGenerator.IL);
			}

			return delegate(CodeGenerator codeGen, PhpTypeCode stackTypeCode)
			{
				// TODO: can we get different PhpTypeCode?
				ILEmitter il = codeGen.IL;
				PropertyDesc.EmitSetConversion(il, stackTypeCode, fieldInfo.FieldType);

				il.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fieldInfo);
			};
		}
예제 #4
0
		internal override AssignmentCallback EmitSet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool isRef,
			ConstructedType constructedType, bool runtimeVisibilityCheck)
		{
			Debug.Assert(IsStatic == (instance == null));

			AdjustConstructedType(ref constructedType);

			if (IsStatic)
			{
				// check the visibility at runtime by the operator:
				if (runtimeVisibilityCheck || UpgradesVisibility)
					return codeGenerator.EmitSetStaticPropertyOperator(DeclaringType, this.FullName, null, isRef);

				if (isRef)
				{
					if (!IsAppStatic) Implementor.EmitThreadStaticInit(codeGenerator, constructedType);

					// just write the PhpReference to the field upon assignment
					return delegate(CodeGenerator codeGen, PhpTypeCode stackTypeCode)
					{
						codeGen.IL.Emit(OpCodes.Stsfld, DType.MakeConstructed(RealField, constructedType));
					};
				}
				else
				{
					// read the PhpReference stored in the field
					EmitGetInternal(codeGenerator, null, true, constructedType, false, false);

					// finish the assignment by writing to its Value field
					return delegate(CodeGenerator codeGen, PhpTypeCode stackTypeCode)
					{
						codeGen.IL.Emit(OpCodes.Stfld, Fields.PhpReference_Value);
					};
				}
			}
			else
			{
				// direct access is possible, however, we have to be prepared for actually calling
				// the operator if the field proves to have been unset

				return delegate(CodeGenerator codeGen, PhpTypeCode stackTypeCode)
				{
					ILEmitter il = codeGen.IL;

					codeGen.EmitLoadSelf();
					instance.EmitLoad(il);
					il.Emit(isRef ? OpCodes.Ldflda : OpCodes.Ldfld, DType.MakeConstructed(RealField, constructedType));
					il.Emit(OpCodes.Ldstr, Name.ToString());
					codeGen.EmitLoadClassContext();

					if (isRef)
					{
						// CALL Operators.SetObjectFieldDirectRef(STACK,<target>,ref <field>,<field name>,<type desc>)
						il.Emit(OpCodes.Call, Methods.Operators.SetObjectFieldDirectRef);
					}
					else
					{
						// CALL Operators.SetObjectFieldDirect(STACK,<target>,<field>,<field name>,<type desc>)
						il.Emit(OpCodes.Call, Methods.Operators.SetObjectFieldDirect);
					}
				};
			}
		}