public override DynamicMetaObject FallbackCreateInstance(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
 {
     // Defer if any object has no value so that we evaulate their
     // Expressions and nest a CallSite for the InvokeMember.
     if (!target.HasValue || args.Any((a) => !a.HasValue))
     {
         var deferArgs = new DynamicMetaObject[args.Length + 1];
         for (int i = 0; i < args.Length; i++)
         {
             deferArgs[i + 1] = args[i];
         }
         deferArgs[0] = target;
         return Defer(deferArgs);
     }
     // Make sure target actually contains a Type.
     if (!typeof(Type).IsAssignableFrom(target.LimitType))
     {
         return errorSuggestion ??
                RuntimeHelpers.CreateBindingThrow(
                    target, args, BindingRestrictions.Empty,
                    typeof(InvalidOperationException),
                    "Type object must be used when creating instance -- " +
                    args);
     }
     var type = target.Value as Type;
     Debug.Assert(type != null);
     ConstructorInfo[] constructors = type.GetConstructors();
     // Get constructors with right arg counts.
     IEnumerable<ConstructorInfo> ctors = constructors.
         Where(c => c.GetParameters().Length == args.Length);
     var res = new List<ConstructorInfo>();
     foreach (ConstructorInfo c in ctors)
     {
         if (RuntimeHelpers.ParametersMatchArguments(c.GetParameters(),
                                                     args))
         {
             res.Add(c);
         }
     }
     // We generate an instance restriction on the target since it is a
     // Type and the constructor is associate with the actual Type instance.
     BindingRestrictions restrictions =
         RuntimeHelpers.GetTargetArgsRestrictions(
             target, args, true);
     if (res.Count == 0)
     {
         return errorSuggestion ??
                RuntimeHelpers.CreateBindingThrow(
                    target, args, restrictions,
                    typeof(MissingMemberException),
                    "Can't bind create instance -- " + args);
     }
     Expression[] ctorArgs =
         RuntimeHelpers.ConvertArguments(
             args, res[0].GetParameters());
     return new DynamicMetaObject(
         // Creating an object, so don't need EnsureObjectResult.
         Expression.New(res[0], ctorArgs),
         restrictions);
 }
Пример #2
0
        public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args) {
            ContractUtils.RequiresNotNull(binder, "binder");

            if (args.Any(arg => ComBinderHelpers.IsStrongBoxArg(arg))) {
                return ComBinderHelpers.RewriteStrongBoxAsRef(binder, this, args, false);
            }

            ComMethodDesc method;
            if (_self.TryGetGetItem(out method)){
                return BindComInvoke(args, method, binder.Arguments);
            }

            return base.BindInvoke(binder, args);
        }
Пример #3
0
 public override DynamicMetaObject FallbackInvoke(
     DynamicMetaObject targetMO, DynamicMetaObject[] argMOs,
     DynamicMetaObject errorSuggestion)
 {
     // First try COM binding.
     DynamicMetaObject result;
     if (ComBinder.TryBindInvoke(this, targetMO, argMOs, out result))
     {
         return result;
     }
     // Defer if any object has no value so that we evaulate their
     // Expressions and nest a CallSite for the InvokeMember.
     if (!targetMO.HasValue || argMOs.Any((a) => !a.HasValue))
     {
         var deferArgs = new DynamicMetaObject[argMOs.Length + 1];
         for (int i = 0; i < argMOs.Length; i++)
         {
             deferArgs[i + 1] = argMOs[i];
         }
         deferArgs[0] = targetMO;
         return Defer(deferArgs);
     }
      //Find our own binding.
     if (targetMO.LimitType.IsSubclassOf(typeof(Delegate)))
     {
         var parms = targetMO.LimitType.GetMethod("Invoke").GetParameters();
         if (parms.Length == argMOs.Length)
         {
             // Don't need to check if argument types match parameters.
             // If they don't, users get an argument conversion error.
             var callArgs = RuntimeHelpers.ConvertArguments(argMOs, parms);
             var expression = Expression.Invoke(
                 Expression.Convert(targetMO.Expression, targetMO.LimitType),
                 callArgs);
             return new DynamicMetaObject(
                 RuntimeHelpers.EnsureObjectResult(expression),
                 BindingRestrictions.GetTypeRestriction(targetMO.Expression,
                     targetMO.LimitType));
         }
     }
     return errorSuggestion ??
         RuntimeHelpers.CreateThrow(
             targetMO, argMOs,
             BindingRestrictions.GetTypeRestriction(targetMO.Expression,
                 targetMO.LimitType),
             typeof(InvalidOperationException),
             "Wrong number of arguments for function -- " +
                 targetMO.LimitType.ToString() + " got " + argMOs.ToString());
 }
Пример #4
0
        private DynamicMetaObject BindGetOrInvoke(CallSiteBinder binder, DynamicMetaObject[] args, IList<ArgumentInfo> argInfos) {
            if (args.Any(arg => ComBinderHelpers.IsStrongBoxArg(arg))) {
                return ComBinderHelpers.RewriteStrongBoxAsRef(binder, this, args, false);
            }

            ComMethodDesc method;
            var target = _callable.DispatchComObject;
            var name = _callable.MemberName;
            
            if (target.TryGetMemberMethod(name, out method) ||
                target.TryGetMemberMethodExplicit(name, out method)) {

                return BindComInvoke(method, args, argInfos);
            }
            return null;
        }
Пример #5
0
        public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value) {
            if (indexes.Any(arg => ComBinderHelpers.IsStrongBoxArg(arg))) {
                return ComBinderHelpers.RewriteStrongBoxAsRef(binder, this, indexes.AddLast(value), true);
            }

            ComMethodDesc method;
            var target = _callable.DispatchComObject;
            var name = _callable.MemberName;

            if (target.TryGetPropertySetter(name, out method, value.LimitType) ||
                target.TryGetPropertySetterExplicit(name, out method, value.LimitType)) {

                return BindComInvoke(method, indexes.AddLast(value), binder.Arguments);
            }

            return base.BindSetIndex(binder, indexes, value);
        }
Пример #6
0
 public override DynamicMetaObject FallbackGetIndex(
     DynamicMetaObject target, DynamicMetaObject[] indexes,
     DynamicMetaObject errorSuggestion)
 {
     // First try COM binding.
     DynamicMetaObject result;
     if (ComBinder.TryBindGetIndex(this, target, indexes, out result))
     {
         return result;
     }
     // Defer if any object has no value so that we evaulate their
     // Expressions and nest a CallSite for the InvokeMember.
     if (!target.HasValue || indexes.Any((a) => !a.HasValue))
     {
         var deferArgs = new DynamicMetaObject[indexes.Length + 1];
         for (int i = 0; i < indexes.Length; i++)
         {
             deferArgs[i + 1] = indexes[i];
         }
         deferArgs[0] = target;
         return Defer(deferArgs);
     }
     // Give good error for Cons.
     //if (target.LimitType == typeof(Cons))
     //{
     //    if (indexes.Length != 1)
     //        return errorSuggestion ??
     //            RuntimeHelpers.CreateThrow(
     //                 target, indexes, BindingRestrictions.Empty,
     //                 typeof(InvalidOperationException),
     //                 "Indexing list takes single index.  " + "Got " +
     //                 indexes.Length.ToString());
     //}
     // Find our own binding.
     //
     // Conversions created in GetIndexExpression must be consistent with
     // restrictions made in GetTargetArgsRestrictions.
     var indexingExpr = RuntimeHelpers.EnsureObjectResult(
         RuntimeHelpers.GetIndexingExpression(target,
             indexes));
     var restrictions = RuntimeHelpers.GetTargetArgsRestrictions(
         target, indexes, false);
     return new DynamicMetaObject(indexingExpr, restrictions);
 }
Пример #7
0
        public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue || args.Any(a => !a.HasValue))
                return Defer(target, args);

            var restrictions = RuntimeHelpers.MergeTypeRestrictions(target);

            if (target.Value == null)
                throw LuaRuntimeException.Create(context, "Attempt to invoke a nil object (" + context.CurrentVariableIdentifier + ")");

            if (!target.LimitType.IsSubclassOf(typeof(Delegate)) && target.LimitType != typeof(Varargs))
                return new DynamicMetaObject(
                    MetamethodFallbacks.WrapStackTrace(MetamethodFallbacks.Call(context, target, args), context,
                    new FunctionStack(context.CurrentVariableIdentifier + "." + Constant.CALL_METAMETHOD)), restrictions);

            restrictions = restrictions.Merge(
                RuntimeHelpers.MergeTypeRestrictions(args).Merge(
                    RuntimeHelpers.MergeInstanceRestrictions(target)));

            Delegate function = null;
            DynamicMetaObject actualTarget = null;
            if (target.LimitType.IsSubclassOf(typeof(Delegate)))
            {
                function = (Delegate)target.Value;
                actualTarget = target;
            }
            else if (target.LimitType == typeof(Varargs))
            {
                function = ((Varargs)target.Value).First() as Delegate;
                actualTarget = new DynamicMetaObject(Expression.Constant(((Varargs)target.Value).First()), BindingRestrictions.Empty, ((Varargs)target.Value).First());
            }

            if (function == null)
                return new DynamicMetaObject(MetamethodFallbacks.Call(context,
                    actualTarget,
                    args),
                    restrictions);

            var methodInfo = function.Method;

            bool toss = false;
            return GetInvoker(actualTarget, args, methodInfo, out toss, ref restrictions);
        }
Пример #8
0
        public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue || args.Any(a => !a.HasValue))
                return Defer(target, args);

            var restrictions = RuntimeHelpers.MergeTypeRestrictions(target);

            if (!target.LimitType.IsSubclassOf(typeof(Delegate)))
                return new DynamicMetaObject(MetamethodFallbacks.Call(context, target, args), restrictions);

            restrictions = restrictions.Merge(
                RuntimeHelpers.MergeTypeRestrictions(args).Merge(
                    RuntimeHelpers.MergeInstanceRestrictions(target)));

            List<Expr> sideEffects;
            Expr failExpr;
            var function = (Delegate)target.Value;
            var methodInfo = function.Method;
            var mappedArgs = MapArguments(args, methodInfo, ref restrictions, out sideEffects, out failExpr);

            if (failExpr != null)
                return new DynamicMetaObject(Expr.Block(failExpr, Expr.Default(typeof(object))), restrictions);

            var invokeExpr = InvokeExpression(target, mappedArgs, methodInfo);

            // Execute overflowing arguments for side effects
            Expr expr;
            if (sideEffects.Count == 0)
            {
                expr = invokeExpr;
            }
            else
            {
                var tempVar = Expr.Variable(typeof(object));
                var assign = Expr.Assign(tempVar, invokeExpr);
                sideEffects.Insert(0, assign);
                sideEffects.Add(tempVar);
                expr = Expr.Block(new[] {tempVar}, sideEffects);
            }

            return new DynamicMetaObject(expr, restrictions);
        }
Пример #9
0
        public override DynamicMetaObject FallbackSetIndex(
            DynamicMetaObject target, DynamicMetaObject[] indexes,
            DynamicMetaObject value, DynamicMetaObject errorSuggestion)
        {
            // First try COM binding.
            DynamicMetaObject result;
            if (ComBinder.TryBindSetIndex(this, target, indexes, value, out result))
            {
                return result;
            }
            // Defer if any object has no value so that we evaulate their
            // Expressions and nest a CallSite for the InvokeMember.
            if (!target.HasValue || indexes.Any((a) => !a.HasValue) || !value.HasValue)
            {
                var deferArgs = new DynamicMetaObject[indexes.Length + 2];
                for (int i = 0; i < indexes.Length; i++)
                {
                    deferArgs[i + 1] = indexes[i];
                }
                deferArgs[0] = target;
                deferArgs[indexes.Length + 1] = value;
                return Defer(deferArgs);
            }
            // Find our own binding.
            Expression valueExpr = value.Expression;
            ////we convert a value of TypeModel to Type.
            //if (value.LimitType == typeof(TypeModel))
            //{
            //    valueExpr = RuntimeHelpers.GetRuntimeTypeMoFromModel(value).Expression;
            //}
            //Debug.Assert(target.HasValue && target.LimitType != typeof(Array));
            Expression setIndexExpr;
            //if (target.LimitType == typeof(Cons))
            //{
            //    if (indexes.Length != 1)
            //    {
            //        return errorSuggestion ??
            //            RuntimeHelpers.CreateThrow(
            //                 target, indexes, BindingRestrictions.Empty,
            //                 typeof(InvalidOperationException),
            //                 "Indexing list takes single index.  " + "Got " + indexes);
            //    }
            //    // Call RuntimeHelper.SetConsElt
            //    List<Expression> args = new List<Expression>();
            //    // The first argument is the list
            //    args.Add(
            //        Expression.Convert(
            //            target.Expression,
            //            target.LimitType)
            //    );
            //    // The second argument is the index.
            //    args.Add(Expression.Convert(indexes[0].Expression,
            //                                indexes[0].LimitType));
            //    // The last argument is the value
            //    args.Add(Expression.Convert(valueExpr, typeof(object)));
            //    // BinderFactory helper returns value stored.
            //    setIndexExpr = Expression.Call(
            //        typeof(RuntimeHelpers),
            //        "SetConsElt",
            //        null,
            //        args.ToArray());
            //}
            //else
            {
                Expression indexingExpr = RuntimeHelpers.GetIndexingExpression(
                    target, indexes);
                // Assign returns the stored value, so we're good for BinderFactory.
                setIndexExpr = Expression.Assign(indexingExpr, valueExpr);
            }

            BindingRestrictions restrictions =
                RuntimeHelpers.GetTargetArgsRestrictions(target, indexes, false);
            return new DynamicMetaObject(
                RuntimeHelpers.EnsureObjectResult(setIndexExpr),
                restrictions);
        }
        public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject targetMO, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            // Defer if any object has no value so that we evaulate their
            // Expressions and nest a CallSite for the InvokeMember.
            if (!targetMO.HasValue || args.Any((a) => !a.HasValue))
            {
                var deferArgs = new DynamicMetaObject[args.Length + 1];
                for (int i = 0; i < args.Length; i++)
                {
                    deferArgs[i + 1] = args[i];
                }
                deferArgs[0] = targetMO;
                return Defer(deferArgs);
            }
            // Find our own binding.
            // Could consider allowing invoking static members from an instance.
            BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
            MemberInfo[] members = targetMO.LimitType.GetMember(Name, flags);
            if ((members.Length == 1) && (members[0] is PropertyInfo ||
                                          members[0] is FieldInfo))
            {
                // NEED TO TEST, should check for delegate value too
                MemberInfo mem = members[0];
                throw new NotImplementedException();
                //return new DynamicMetaObject(
                //    Expression.Dynamic(
                //        new SymplInvokeBinder(new CallInfo(args.Length)),
                //        typeof(object),
                //        args.Select(a => a.Expression).AddFirst(
                //               Expression.MakeMemberAccess(this.Expression, mem)));

                // Don't test for eventinfos since we do nothing with them now.
            }
            else
            {
                // Get MethodInfos with right arg counts.
                IEnumerable<MethodInfo> mi_mems = members.
                    Select(m => m as MethodInfo).
                    Where(m => m.GetParameters().Length == args.Length);
                // Get MethodInfos with param types that work for args.  This works
                // except for value args that need to pass to reftype params.
                // We could detect that to be smarter and then explicitly StrongBox
                // the args.
                var res = mi_mems.Where(mem => RuntimeHelpers.ParametersMatchArguments(mem.GetParameters(), args)).ToList();
                // False below means generate a type restriction on the MO.
                // We are looking at the members targetMO's Type.
                BindingRestrictions restrictions = RuntimeHelpers.GetTargetArgsRestrictions(targetMO, args, false);
                if (res.Count == 0)
                {
                    return errorSuggestion ?? RuntimeHelpers.CreateBindingThrow(targetMO, args, restrictions, typeof(MissingMemberException), "Can't bind member invoke -- " + args);
                }
                // restrictions and conversion must be done consistently.
                Expression[] callArgs = RuntimeHelpers.ConvertArguments(args, res[0].GetParameters());
                return new DynamicMetaObject(
                    RuntimeHelpers.EnsureObjectResult(
                        Expression.Call(
                            Expression.Convert(targetMO.Expression, targetMO.LimitType),
                            res[0],
                            callArgs)),
                    restrictions);
                // Could hve tried just letting Expr.Call factory do the work,
                // but if there is more than one applicable method using just
                // assignablefrom, Expr.Call throws.  It does not pick a "most
                // applicable" method or any method.
            }
        }
Пример #11
0
 internal static bool NeedsDeferal(DynamicMetaObject[] args)
 {
     return args.Any(MetaObjectExtensions.NeedsDeferral);
 }
Пример #12
0
        public override DynamicMetaObject FallbackInvokeMember(
            DynamicMetaObject target, DynamicMetaObject[] args,
            DynamicMetaObject errorSuggestion)
        {
            // First try COM binding.
            DynamicMetaObject result;
            if (ComBinder.TryBindInvokeMember(this, target, args, out result))
                return result;

            // Defer if any object has no value so that we evaulate their
            // Expressions and nest a CallSite for the InvokeMember.
            if (!target.HasValue || args.Any((a) => !a.HasValue))
            {
                var deferArgs = new DynamicMetaObject[args.Length + 1];
                for (int i = 0; i < args.Length; i++)
                {
                    deferArgs[i + 1] = args[i];
                }
                deferArgs[0] = target;
                return Defer(deferArgs);
            }

            Func<DynamicMetaObject> getMethodNotFoundDMO = () => errorSuggestion ?? RuntimeHelpers.CreateThrow(target, args, RuntimeHelpers.GetTargetArgsRestrictions(target, args, false),
                    typeof(MissingMethodException), String.Format(RuntimeMessages.PublicMethodDoesNotExist_Method_Type, this.Name, target.Value.GetType()));

            if (target.Value is HappyTypeTracker)
            {
                HappyTypeTracker typeTracker = (HappyTypeTracker) target.Value;
                IHappyTracker found;

                if (typeTracker.FindMemberTracker(this.Name, out found))
                {
                    HappyMethodTracker tracker = found as HappyMethodTracker;
                    if(tracker == null)
                    {
                        return errorSuggestion ??
                                    RuntimeHelpers.CreateThrow(
                                        target, args, RuntimeHelpers.GetTargetArgsRestrictions(target, args, false),
                                        typeof(MissingMemberException),
                                        String.Format(RuntimeMessages.MemberIsNotInvokable_MemberNameTypeName, found.Name, typeTracker.Name), args.ToString());
                    }
                    return ResolveOverload(null, args, tracker.Methods, BindingRestrictions.GetInstanceRestriction(target.Expression, typeTracker));
                }

                return getMethodNotFoundDMO();
            }

            MethodInfo[] methods = target.Value.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public).Where(m => m.Name == Name).ToArray();

            if(methods.Length != 0)
                return this.ResolveOverload(target, args, methods);

            return getMethodNotFoundDMO();
        }
Пример #13
0
        public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value) {
            ContractUtils.RequiresNotNull(binder, "binder");

            if (indexes.Any(arg => ComBinderHelpers.IsStrongBoxArg(arg))) {
                return ComBinderHelpers.RewriteStrongBoxAsRef(binder, this, indexes.AddLast(value), true);
            }

            ComMethodDesc setItem;
            if (_self.TryGetSetItem(out setItem)) {
                return BindComInvoke(indexes.AddLast(value), setItem, binder.Arguments);
            }

            return base.BindSetIndex(binder, indexes, value);
        }