internal override PhpTypeCode EmitGet(CodeGenerator /*!*/ codeGenerator, ConstructedType constructedType, bool runtimeVisibilityCheck, string fallbackName) { Debug.Assert(fallbackName == null); codeGenerator.EmitGetConstantValueOperator(declaringType, this.FullName, null); return(PhpTypeCode.Object); }
internal override PhpTypeCode EmitGet(CodeGenerator codeGenerator, ConstructedType constructedType, bool runtimeVisibilityCheck, string fallbackName) { if (!HasValue) { // __InitializeStaticFields to ensure, this deferred constant has been initialized (same as thread static field): DeclaringPhpType.EmitThreadStaticInit(codeGenerator, constructedType); } return(base.EmitGet(codeGenerator, constructedType, runtimeVisibilityCheck, fallbackName)); }
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)); } }
internal abstract void EmitUnset(CodeGenerator/*!*/ codeGenerator, IPlace/*!*/ instance, ConstructedType constructedType, bool runtimeVisibilityCheck);
internal abstract PhpTypeCode EmitGet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool wantRef, ConstructedType constructedType, bool runtimeVisibilityCheck);
internal override AssignmentCallback EmitSet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool isRef, ConstructedType constructedType, bool runtimeVisibilityCheck) { Debug.Fail(); return null; }
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); }; }
internal override void EmitUnset(CodeGenerator codeGenerator/*!*/, IPlace/*!*/ instance, ConstructedType constructedType, bool runtimeVisibilityCheck) { // TODO: }
internal override PhpTypeCode EmitGet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool wantRef, ConstructedType constructedType, bool runtimeVisibilityCheck) { Debug.Assert(IsStatic == (instance == null)); Debug.Assert(hasGetter, "TODO"); ILEmitter il = codeGenerator.IL; if (IsStatic) { if (runtimeVisibilityCheck) { // let the operator to check the visibility: return codeGenerator.EmitGetStaticPropertyOperator(DeclaringType, this.FullName, null, wantRef); } } else { instance.EmitLoad(il); } MethodInfo getter = this.Getter; il.Emit(getter.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, getter); PhpTypeCode result = ClrOverloadBuilder.EmitConvertToPhp(il, getter.ReturnType/*, codeGenerator.ScriptContextPlace*/); codeGenerator.EmitReferenceDereference(ref result, wantRef); return result; }
internal override void EmitUnset(CodeGenerator codeGenerator, Core.Emit.IPlace instance, ConstructedType constructedType, bool runtimeVisibilityCheck) { throw null; }
internal override PhpTypeCode EmitGet(CodeGenerator /*!*/ codeGenerator, ConstructedType constructedType, bool runtimeVisibilityCheck, string fallbackName) { codeGenerator.EmitGetConstantValueOperator(null, this.FullName, fallbackName); return(PhpTypeCode.Object); }
internal abstract PhpTypeCode EmitGet(CodeGenerator /*!*/ codeGenerator, ConstructedType constructedType, bool runtimeVisibilityCheck, string fallbackName);
internal override PhpTypeCode EmitGet(CodeGenerator codeGenerator, ConstructedType constructedType, bool runtimeVisibilityCheck, string fallbackName) { if (!HasValue) { // __InitializeStaticFields to ensure, this deferred constant has been initialized (same as thread static field): DeclaringPhpType.EmitThreadStaticInit(codeGenerator, constructedType); } return base.EmitGet(codeGenerator, constructedType, runtimeVisibilityCheck, fallbackName); }
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); } }
internal override PhpTypeCode EmitGet(CodeGenerator/*!*/ codeGenerator, ConstructedType constructedType, bool runtimeVisibilityCheck, string fallbackName) { codeGenerator.EmitGetConstantValueOperator(null, this.FullName, fallbackName); return PhpTypeCode.Object; }
internal override AssignmentCallback EmitSet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool isRef, ConstructedType constructedType, bool runtimeVisibilityCheck) { return codeGenerator.EmitSetStaticPropertyOperator(declaringType, this.FullName, null, isRef); }
internal override PhpTypeCode EmitGet(CodeGenerator codeGenerator, Core.Emit.IPlace instance, bool wantRef, ConstructedType constructedType, bool runtimeVisibilityCheck) { throw null; }
internal ConstructedType/*!*/ CreateConstructedType(DTypeDesc/*!*/ genericType, DTypeDesc[]/*!!*/ arguments, int argCount) { ConstructedType result; if (genericType.IsUnknown) { Array.Resize(ref arguments, argCount); result = new ConstructedType(genericType, arguments); } else { DTypeDescs tuple = new DTypeDescs(genericType, arguments, argCount); if (!constructedTypes.TryGetValue(tuple, out result)) { Array.Resize(ref arguments, argCount); result = new ConstructedType(genericType, arguments); constructedTypes.Add(tuple, result); } } return result; }
internal override PhpTypeCode EmitGet(CodeGenerator/*!*/ codeGenerator, ConstructedType constructedType, bool runtimeVisibilityCheck, string fallbackName) { Debug.Assert(fallbackName == null); codeGenerator.EmitGetConstantValueOperator(declaringType, this.FullName, null); return PhpTypeCode.Object; }
/// <summary> /// Returns parameters and return type remapped according to a constructed type. /// </summary> public ParameterInfo[]/*!*/ MakeConstructed(ConstructedType constructedType, out Type/*!*/ returnType) { MethodInfo method_info = method as MethodInfo; returnType = (method_info != null ? method_info.ReturnType : Types.Void); if (constructedType != null) { returnType = constructedType.MapRealType(returnType); ParameterInfo[] new_params = new ParameterInfo[parameters.Length]; for (int i = 0; i < new_params.Length; i++) { ParameterInfo param_info = parameters[i]; new_params[i] = new StubParameterInfo( param_info.Position, constructedType.MapRealType(param_info.ParameterType), param_info.Attributes, param_info.Name); } return new_params; } else { return parameters; } }
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); }; }
private void AdjustConstructedType(ref ConstructedType constructedType) { if (constructedType == null) return; DTypeDesc implementor_desc = Implementor.TypeDesc; // adjust constructed type according to the implementor // TODO: this does not work while (constructedType.GenericType != implementor_desc) { constructedType = constructedType.Base as ConstructedType; if (constructedType == null) return; } }
internal override PhpTypeCode EmitGet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool wantRef, ConstructedType constructedType, bool runtimeVisibilityCheck) { Debug.Assert(IsStatic == (instance == null)); ILEmitter il = codeGenerator.IL; if (IsStatic) { if (runtimeVisibilityCheck) { // let the operator to check the visibility: return codeGenerator.EmitGetStaticPropertyOperator(DeclaringType, this.FullName, null, wantRef); } il.Emit(OpCodes.Ldsfld, fieldInfo); } else { instance.EmitLoad(il); il.Emit(OpCodes.Ldfld, fieldInfo); } PhpTypeCode result = ClrOverloadBuilder.EmitConvertToPhp(il, fieldInfo.FieldType/*, codeGenerator.ScriptContextPlace*/); codeGenerator.EmitReferenceDereference(ref result, wantRef); return result; }
private PhpTypeCode EmitGetInternal(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool wantRef, ConstructedType constructedType, bool runtimeVisibilityCheck, bool setAliasedFlag) { ILEmitter il = codeGenerator.IL; if (IsStatic) { if (runtimeVisibilityCheck || UpgradesVisibility) { // let the operator to check the visibility: return codeGenerator.EmitGetStaticPropertyOperator(DeclaringType, this.FullName, null, wantRef); } if (!IsAppStatic) Implementor.EmitThreadStaticInit(codeGenerator, constructedType); // retrieve field value il.Emit(OpCodes.Ldsfld, DType.MakeConstructed(RealField, constructedType)); if (wantRef) { if (setAliasedFlag) { // set IsAliased to true il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldc_I4_1); il.EmitCall(OpCodes.Callvirt, Properties.PhpReference_IsAliased.GetSetMethod(), null); } return PhpTypeCode.PhpReference; } else { il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value); return PhpTypeCode.Object; } } else { // LOAD Operators.GetObjectFieldDirect[Ref](this,this.<field>,<name>,<type desc>,[<quiet>]); codeGenerator.EmitLoadSelf(); instance.EmitLoad(il); il.Emit(OpCodes.Ldfld, DType.MakeConstructed(RealField, constructedType)); il.Emit(OpCodes.Ldstr, Name.ToString()); codeGenerator.EmitLoadClassContext(); if (wantRef) { il.Emit(OpCodes.Call, Methods.Operators.GetObjectFieldDirectRef); return PhpTypeCode.PhpReference; } else { il.LoadBool(codeGenerator.ChainBuilder.QuietRead); il.Emit(OpCodes.Call, Methods.Operators.GetObjectFieldDirect); return PhpTypeCode.Object; } } }
internal override PhpTypeCode EmitGet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool wantRef, ConstructedType constructedType, bool runtimeVisibilityCheck) { Debug.Assert(IsStatic == (instance == null)); ILEmitter il = codeGenerator.IL; if (IsStatic && runtimeVisibilityCheck) { // let the operator to check the visibility: return codeGenerator.EmitGetStaticPropertyOperator(DeclaringType, this.FullName, null, wantRef); } EmitGetEventObject(il, codeGenerator.ScriptContextPlace, instance, false); if (wantRef) il.Emit(OpCodes.Newobj, Constructors.PhpReference_Object); return (wantRef ? PhpTypeCode.PhpReference : PhpTypeCode.DObject); }
internal override PhpTypeCode EmitGet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool wantRef, ConstructedType constructedType, bool runtimeVisibilityCheck) { Debug.Assert(IsStatic == (instance == null)); AdjustConstructedType(ref constructedType); return EmitGetInternal(codeGenerator, instance, wantRef, constructedType, runtimeVisibilityCheck, true); }
internal override void EmitUnset(CodeGenerator/*!*/ codeGenerator, IPlace/*!*/ instance, ConstructedType constructedType, bool runtimeVisibilityCheck) { Debug.Fail(); }
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); } }; } }
internal abstract AssignmentCallback EmitSet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool isRef, ConstructedType constructedType, bool runtimeVisibilityCheck);
internal override void EmitUnset(CodeGenerator/*!*/ codeGenerator, IPlace/*!*/ instance, ConstructedType constructedType, bool runtimeVisibilityCheck) { ILEmitter il = codeGenerator.IL; if (IsStatic) { // emit error (whether or not the property is visible): il.Emit(OpCodes.Ldstr, DeclaringType.FullName); il.Emit(OpCodes.Ldstr, this.FullName); codeGenerator.EmitPhpException(Methods.PhpException.StaticPropertyUnset); return; } // replace the field with a new PhpSmartReference with IsSet false instance.EmitLoad(il); il.Emit(OpCodes.Newobj, Constructors.PhpSmartReference.Void); il.Emit(OpCodes.Dup); il.LoadBool(false); il.Emit(OpCodes.Callvirt, Properties.PhpReference_IsSet.GetSetMethod()); il.Emit(OpCodes.Stfld, DType.MakeConstructed(RealField, constructedType)); }
internal override PhpTypeCode EmitGet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool wantRef, ConstructedType constructedType, bool runtimeVisibilityCheck) { return codeGenerator.EmitGetStaticPropertyOperator(declaringType, this.FullName, null, wantRef); }
internal override PhpTypeCode EmitGet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool wantRef, ConstructedType constructedType, bool runtimeVisibilityCheck) { Debug.Assert(IsStatic == (instance == null)); ILEmitter il = codeGenerator.IL; var getter = RealProperty.GetGetMethod(); if (getter == null) throw new MissingMethodException(string.Format("'{0}.get_{1}' not implemented!", RealProperty.DeclaringType.Name, RealProperty.Name)); // <this>. if (!IsStatic) instance.EmitLoad(il); // getter() il.Emit(OpCodes.Call, getter); // handle references if (wantRef) { // make reference if (Types.PhpReference[0].IsAssignableFrom(getter.ReturnType)) { EmitIsAliased(il); } else { throw new NotImplementedException(); } // return PhpTypeCode.PhpReference; } else { // dereference if (Types.PhpReference[0].IsAssignableFrom(getter.ReturnType)) { EmitIsAliased(il); il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value); } else { il.EmitBoxing(PhpTypeCodeEnum.FromType(getter.ReturnType)); } // return PhpTypeCode.Object; } }
internal override void EmitUnset(CodeGenerator/*!*/ codeGenerator, IPlace instance, ConstructedType constructedType, bool runtimeVisibilityCheck) { codeGenerator.EmitUnsetStaticPropertyOperator(declaringType, this.FullName, null); }
internal override AssignmentCallback EmitSet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool isRef, ConstructedType constructedType, bool runtimeVisibilityCheck) { ILEmitter il = codeGenerator.IL; var setter = RealProperty.GetSetMethod(); if (setter == null) throw new MissingMethodException(string.Format("'{0}.set_{1}' not implemented!", RealProperty.DeclaringType.Name, RealProperty.Name)); // <this>. if (!IsStatic) instance.EmitLoad(il); // setter() return delegate(CodeGenerator codeGen, PhpTypeCode stackTypeCode) { var parameters = setter.GetParameters(); if (isRef && parameters[0].ParameterType != Types.PhpReference[0]) { // .setter(<stack>.Value) codeGen.IL.Emit(OpCodes.Ldfld, Fields.PhpReference_Value); codeGen.IL.Emit(OpCodes.Call, setter); } else if (!isRef && parameters[0].ParameterType == Types.PhpReference[0]) { // .getter().Value = <stack> codeGen.IL.Emit(OpCodes.Call, RealProperty.GetGetMethod()); codeGen.IL.Emit(OpCodes.Stfld, Fields.PhpReference_Value); } else { // .setter(<stack>) codeGen.IL.Emit(OpCodes.Call, setter); } }; }
internal override AssignmentCallback EmitSet(CodeGenerator codeGenerator, Core.Emit.IPlace instance, bool isRef, ConstructedType constructedType, bool runtimeVisibilityCheck) { throw null; }
internal override void EmitUnset(CodeGenerator/*!*/ codeGenerator, IPlace/*!*/ instance, ConstructedType constructedType, bool runtimeVisibilityCheck) { ILEmitter il = codeGenerator.IL; if (IsStatic) { // emit error (whether or not the property is visible): il.Emit(OpCodes.Ldstr, DeclaringType.FullName); il.Emit(OpCodes.Ldstr, this.FullName); codeGenerator.EmitPhpException(Methods.PhpException.StaticPropertyUnset); return; } throw new NotImplementedException(); }
public ClrOverloadBuilder(ILEmitter/*!*/ il, ClrMethod/*!*/ method, ConstructedType constructedType, IPlace/*!*/ stack, IPlace/*!*/ instance, bool emitParentCtorCall, ParameterLoader/*!*/ loadValueArg, ParameterLoader/*!*/ loadReferenceArg) { this.il = il; this.method = method; this.constructedType = constructedType; this.stack = stack; this.instance = instance; this.loadValueArg = loadValueArg; this.loadReferenceArg = loadReferenceArg; this.emitParentCtorCall = emitParentCtorCall; this.overloads = new List<Overload>(method.Overloads); SortOverloads(this.overloads); }
internal abstract PhpTypeCode EmitGet(CodeGenerator/*!*/ codeGenerator, ConstructedType constructedType, bool runtimeVisibilityCheck, string fallbackName);