Exemple #1
0
            /// <summary>
            /// Creates Func&lt;object, T&gt; 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());
            }
Exemple #2
0
            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());
            }
Exemple #3
0
            public ClrFieldProperty(PhpTypeInfo tinfo, FieldInfo field)
                : base(tinfo)
            {
                _field = field ?? throw new ArgumentNullException(nameof(field));

                //
                _lazyGetter       = new Lazy <Func <object, PhpValue> >(() => (Func <object, PhpValue>)CompileAccess(AccessMask.Read));
                _lazyEnsureAlias  = new Lazy <Func <object, PhpAlias> >(() => (Func <object, PhpAlias>)CompileAccess(AccessMask.ReadRef));
                _lazyEnsureObject = new Lazy <Func <object, object> >(() => (Func <object, object>)CompileAccess(AccessMask.EnsureObject));
                _lazyEnsureArray  = new Lazy <Func <object, IPhpArray> >(() => (Func <object, IPhpArray>)CompileAccess(AccessMask.EnsureArray));

                // 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, _field.DeclaringType));

                    // expr: <field> := <value>
                    expr = BinderHelpers.BindAccess(expr, pctx, AccessMask.Write, pvalue);

                    //
                    var lambda = Expression.Lambda(Expression.Block(expr, Expression.Empty()), pctx, pinstance, pvalue);

                    return((Action <Context, object, PhpValue>)lambda.Compile());
                });
            }