/// <summary> /// Creates Func<object, T> depending on the access. /// </summary> Delegate CompileAccess(AccessMask access) { var pinstance = Expression.Parameter(typeof(object)); var expr = Bind(null, Expression.Convert(pinstance, _field.DeclaringType)); if (access == AccessMask.Read) { expr = ConvertExpression.BindToValue(expr); } else { expr = BinderHelpers.BindAccess(expr, null, access, null); } return(Expression.Lambda(expr, true, pinstance).Compile()); }
public ClrProperty(PhpTypeInfo tinfo, PropertyInfo property) : base(tinfo) { Debug.Assert(property != null); _property = property; _lazyGetter = new Lazy <Func <object, PhpValue> >(() => { var pinstance = Expression.Parameter(typeof(object)); var expr = Bind(null, Expression.Convert(pinstance, _property.DeclaringType)); expr = ConvertExpression.BindToValue(expr); // return((Func <object, PhpValue>)Expression.Lambda(expr, true, pinstance).Compile()); }); // SetValue(instance, PhpValue): void _lazySetValue = new Lazy <Action <Context, object, PhpValue> >(() => { if (IsReadOnly) { // error return(new Action <Context, object, PhpValue>((_, _instance, _value) => { PhpException.ErrorException(Resources.ErrResources.readonly_property_written, ContainingType.Name, PropertyName); })); } var pctx = Expression.Parameter(typeof(Context)); var pinstance = Expression.Parameter(typeof(object)); var pvalue = Expression.Parameter(typeof(PhpValue)); // expr: <instance>.<field> var expr = Bind(pctx, Expression.Convert(pinstance, _property.DeclaringType)); // expr: <property> := <value> expr = Expression.Assign(expr, ConvertExpression.Bind(pvalue, expr.Type, pctx)); // TODO: PHP semantic (Operators.SetValue) // {expr}: void var lambda = Expression.Lambda(Expression.Block(expr, Expression.Empty()), pctx, pinstance, pvalue); return((Action <Context, object, PhpValue>)lambda.Compile()); }); }
Delegate CompileAccess(AccessMask access) { var pctx = Expression.Parameter(typeof(Context)); var pinstance = Expression.Parameter(typeof(object)); var expr = Bind(pctx, Expression.Convert(pinstance, Field.DeclaringType)); if (access == AccessMask.Read) { expr = ConvertExpression.BindToValue(expr); } else { expr = BinderHelpers.BindAccess(expr, null, access, null); } // return(Expression.Lambda(expr, tailCall: true, parameters: new[] { pctx, pinstance }).Compile()); }