Esempio n. 1
0
 public DynamicMetaObject ConvertWorker(DynamicMetaObjectBinder binder, Type toType, ConversionResultKind kind)
 {
     PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Convert");
     PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass Convert");
     if (toType.IsSubclassOf(typeof(Delegate)))
     {
         return(MakeDelegateTarget(binder, toType, Restrict(typeof(OldClass))));
     }
     return(FallbackConvert(binder));
 }
Esempio n. 2
0
        /// <summary>
        /// Creates the LambdaExpression which is the actual function body.
        /// </summary>
        private LightLambdaExpression EnsureFunctionLambda()
        {
            if (_dlrBody == null)
            {
                PerfTrack.NoteEvent(PerfTrack.Categories.Compiler, "Creating FunctionBody");
                _dlrBody = CreateFunctionLambda();
            }

            return(_dlrBody);
        }
Esempio n. 3
0
        internal override LightLambdaExpression GetLambda()
        {
            if (_dlrBody == null)
            {
                PerfTrack.NoteEvent(PerfTrack.Categories.Compiler, "Creating FunctionBody");
                _dlrBody = MakeClassBody();
            }

            return(_dlrBody);
        }
Esempio n. 4
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass PythonOperation " + action.Operation);

            if (action.Operation == PythonOperationKind.IsCallable)
            {
                return(MakeIsCallable(action));
            }

            return(null);
        }
Esempio n. 5
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "BuiltinFunc Operation " + action.Operation);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "BuiltinFunc Operation");
            switch (action.Operation)
            {
            case PythonOperationKind.CallSignatures:
                return(PythonProtocol.MakeCallSignatureOperation(this, Value.Targets));
            }

            return(null);
        }
Esempio n. 6
0
        public void DumpDebugInfo()
        {
#if FULL
            if (ScriptDomainManager.Options.EngineDebug)
            {
                PerfTrack.DumpStats();
                try {
                    ScriptDomainManager.CurrentManager.Snippets.Dump();
                } catch (NotSupportedException) { } // usually not important info...
            }
#endif
        }
Esempio n. 7
0
        internal static bool TryInvokeTernaryOperator(CodeContext context, object o, object arg1, object arg2, string name, out object value)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Temporary, "TernaryOp " + CompilerHelpers.GetType(o).Name + " " + name);

            if (TryGetOperator(context, o, name, out object callable))
            {
                value = PythonCalls.Call(context, callable, arg1, arg2);
                return(true);
            }

            value = null;
            return(false);
        }
Esempio n. 8
0
        private DynamicMetaObject /*!*/ MakeCallRule(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Invoke w/ " + args.Length + " args");
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass Invoke");

            CallSignature signature = BindingHelpers.GetCallSignature(call);

            // TODO: If we know __init__ wasn't present we could construct the OldInstance directly.

            Expression[] exprArgs = new Expression[args.Length];
            for (int i = 0; i < args.Length; i++)
            {
                exprArgs[i] = args[i].Expression;
            }

            ParameterExpression init    = Ast.Variable(typeof(object), "init");
            ParameterExpression instTmp = Ast.Variable(typeof(object), "inst");
            DynamicMetaObject   self    = Restrict(typeof(OldClass));

            return(new DynamicMetaObject(
                       Ast.Block(
                           new ParameterExpression[] { init, instTmp },
                           Ast.Assign(
                               instTmp,
                               Ast.New(
                                   typeof(OldInstance).GetConstructor(new Type[] { typeof(CodeContext), typeof(OldClass) }),
                                   codeContext,
                                   self.Expression
                                   )
                               ),
                           Ast.Condition(
                               Ast.Call(
                                   typeof(PythonOps).GetMethod("OldClassTryLookupInit"),
                                   self.Expression,
                                   instTmp,
                                   init
                                   ),
                               Ast.Dynamic(
                                   PythonContext.GetPythonContext(call).Invoke(
                                       signature
                                       ),
                                   typeof(object),
                                   ArrayUtils.Insert <Expression>(codeContext, init, exprArgs)
                                   ),
                               NoInitCheckNoArgs(signature, self, args)
                               ),
                           instTmp
                           ),
                       self.Restrictions.Merge(BindingRestrictions.Combine(args))
                       ));
        }
Esempio n. 9
0
        internal override bool TryGetValue(CodeContext context, object instance, PythonType owner, out object value)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Fields, this);
            if (instance == null)
            {
                value = _info.IsStatic ? _info.GetValue(null) : this;
            }
            else
            {
                value = _info.GetValue(context.LanguageContext.Binder.Convert(instance, _info.DeclaringType));
            }

            return(true);
        }
        internal static DynamicMetaObject FallbackWorker(PythonContext context, DynamicMetaObject /*!*/ self, DynamicMetaObject /*!*/ codeContext, string name, GetMemberOptions options, DynamicMetaObjectBinder action, DynamicMetaObject errorSuggestion)
        {
            if (self.NeedsDeferral())
            {
                return(action.Defer(self));
            }
            PythonOverloadResolverFactory resolverFactory = new PythonOverloadResolverFactory(context.Binder, codeContext.Expression);

            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "FallbackGet");

            bool isNoThrow = ((options & GetMemberOptions.IsNoThrow) != 0) ? true : false;
            Type limitType = self.GetLimitType();

            if (limitType == typeof(DynamicNull) || PythonBinder.IsPythonType(limitType))
            {
                // look up in the PythonType so that we can
                // get our custom method names (e.g. string.startswith)
                PythonType argType = DynamicHelpers.GetPythonTypeFromType(limitType);

                // if the name is defined in the CLS context but not the normal context then
                // we will hide it.
                if (argType.IsHiddenMember(name))
                {
                    DynamicMetaObject baseRes = PythonContext.GetPythonContext(action).Binder.GetMember(
                        name,
                        self,
                        resolverFactory,
                        isNoThrow,
                        errorSuggestion
                        );
                    Expression failure = GetFailureExpression(limitType, self, name, isNoThrow, action);

                    return(BindingHelpers.FilterShowCls(codeContext, action, baseRes, failure));
                }
            }

            var res = PythonContext.GetPythonContext(action).Binder.GetMember(name, self, resolverFactory, isNoThrow, errorSuggestion);

            // Default binder can return something typed to boolean or int.
            // If that happens, we need to apply Python's boxing rules.
            if (res.Expression.Type.IsValueType)
            {
                res = new DynamicMetaObject(
                    AstUtils.Convert(res.Expression, typeof(object)),
                    res.Restrictions
                    );
            }

            return(res);
        }
        public DynamicMetaObject ConvertWorker(DynamicMetaObjectBinder binder, Type type, Type retType, ConversionResultKind kind)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Conversion " + type.FullName);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Conversion");
            ValidationInfo typeTest = BindingHelpers.GetValidationInfo(this, Value.PythonType);

            return(BindingHelpers.AddDynamicTestAndDefer(
                       binder,
                       TryPythonConversion(binder, type) ?? FallbackConvert(binder),
                       new DynamicMetaObject[] { this },
                       typeTest,
                       retType
                       ));
        }
        private void DoSet(CodeContext context, object instance, object val, bool suppressWarning)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Fields, this);
            if (_info.IsInitOnly || _info.IsLiteral)
            {
                throw PythonOps.AttributeErrorForReadonlyAttribute(_info.DeclaringType.Name, _info.Name);
            }
            else if (!suppressWarning && instance != null && instance.GetType().IsValueType)
            {
                PythonOps.Warn(context, PythonExceptions.RuntimeWarning, UpdateValueTypeFieldWarning, _info.Name, _info.DeclaringType.Name);
            }

            _info.SetValue(instance, context.LanguageContext.Binder.Convert(val, _info.FieldType));
        }
Esempio n. 13
0
        private DynamicMetaObject /*!*/ MakeSetMember(string /*!*/ name, DynamicMetaObject /*!*/ value)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass SetMember");
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass SetMember");
            DynamicMetaObject self = Restrict(typeof(OldClass));

            Expression call, valueExpr = AstUtils.Convert(value.Expression, typeof(object));

            switch (name)
            {
            case "__bases__":
                call = Ast.Call(
                    typeof(PythonOps).GetMethod("OldClassSetBases"),
                    self.Expression,
                    valueExpr
                    );
                break;

            case "__name__":
                call = Ast.Call(
                    typeof(PythonOps).GetMethod("OldClassSetName"),
                    self.Expression,
                    valueExpr
                    );
                break;

            case "__dict__":
                call = Ast.Call(
                    typeof(PythonOps).GetMethod("OldClassSetDictionary"),
                    self.Expression,
                    valueExpr
                    );
                break;

            default:
                call = Ast.Call(
                    typeof(PythonOps).GetMethod("OldClassSetNameHelper"),
                    self.Expression,
                    AstUtils.Constant(name),
                    valueExpr
                    );
                break;
            }

            return(new DynamicMetaObject(
                       call,
                       self.Restrictions.Merge(value.Restrictions)
                       ));
        }
Esempio n. 14
0
        protected override T MakeTarget(CodeContext context)
        {
            if (_rules.Count == 1 && this != _rules[0].MonomorphicRuleSet)
            {
                // use the monomorphic rule if we only have 1 rule.
                return(_rules[0].MonomorphicRuleSet.GetOrMakeTarget(context));
            }

            PerfTrack.NoteEvent(PerfTrack.Categories.Rules, "GenerateRule");

            MethodInfo mi = typeof(T).GetMethod("Invoke");
            CodeGen    cg = ScriptDomainManager.CurrentManager.Snippets.Assembly.DefineMethod(
                StubName,
                mi.ReturnType,
                ReflectionUtils.GetParameterTypes(mi.GetParameters()),
                new ConstantPool()
                );

            cg.EmitLineInfo = false;
            cg.Binder       = context.LanguageContext.Binder;

            if (DynamicSiteHelpers.IsFastTarget(typeof(T)))
            {
                cg.ContextSlot = new PropertySlot(cg.ArgumentSlots[0], typeof(FastDynamicSite).GetProperty("Context"));
            }
            else
            {
                cg.ContextSlot = cg.ArgumentSlots[1];
            }

            foreach (StandardRule <T> rule in _rules)
            {
                Label nextTest = cg.DefineLabel();
                rule.Emit(cg, nextTest);
                cg.MarkLabel(nextTest);
            }
            EmitNoMatch(cg);

            if (_rules.Count == 1 &&
                this == _rules[0].MonomorphicRuleSet &&
                _rules[0].TemplateParameterCount > 0 &&
                cg.IsDynamicMethod)
            {
                _monomorphicTemplate = (DynamicMethod)cg.MethodInfo;
            }

            return((T)(object)cg.CreateDelegate(typeof(T)));
        }
Esempio n. 15
0
        private DynamicMetaObject /*!*/ InvokeWorker(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "BuiltinMethodDesc Invoke " + Value.DeclaringType + "." + Value.__name__ + " w/ " + args.Length + " args");
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "BuiltinMethodDesc Invoke");

            CallSignature       signature    = BindingHelpers.GetCallSignature(call);
            BindingRestrictions selfRestrict = BindingRestrictions.GetInstanceRestriction(Expression, Value).Merge(Restrictions);

            selfRestrict = selfRestrict.Merge(
                BindingRestrictions.GetExpressionRestriction(
                    MakeFunctionTest(
                        Ast.Call(
                            typeof(PythonOps).GetMethod("GetBuiltinMethodDescriptorTemplate"),
                            Ast.Convert(Expression, typeof(BuiltinMethodDescriptor))
                            )
                        )
                    )
                );

            return(Value.Template.MakeBuiltinFunctionCall(
                       call,
                       codeContext,
                       this,
                       args,
                       false, // no self
                       selfRestrict,
                       (newArgs) => {
                BindingTarget target;
                PythonContext state = PythonContext.GetPythonContext(call);

                DynamicMetaObject res = state.Binder.CallMethod(
                    new PythonOverloadResolver(
                        state.Binder,
                        newArgs,
                        signature,
                        codeContext
                        ),
                    Value.Template.Targets,
                    selfRestrict,
                    Value.Template.Name,
                    NarrowingLevel.None,
                    Value.Template.IsBinaryOperator ? PythonNarrowing.BinaryOperator : NarrowingLevel.All,
                    out target
                    );

                return BindingHelpers.CheckLightThrow(call, res, target);
            }));
        }
Esempio n. 16
0
        private DynamicMetaObject /*!*/ MakeDeleteMember(DeleteMemberBinder /*!*/ member)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass DeleteMember");
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass DeleteMember");
            DynamicMetaObject self = Restrict(typeof(OldClass));

            return(new DynamicMetaObject(
                       Ast.Call(
                           typeof(PythonOps).GetMethod("OldClassDeleteMember"),
                           AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext),
                           self.Expression,
                           AstUtils.Constant(member.Name)
                           ),
                       self.Restrictions
                       ));
        }
        public override DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ scopeOrContextOrTargetOrArgArray, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Ruby: " + GetType().Name + Signature.ToString() + ": Bind");

            var callArgs    = new CallArguments(_context, scopeOrContextOrTargetOrArgArray, args, Signature);
            var metaBuilder = new MetaObjectBuilder(this, args);

            DynamicMetaObject interopBinding;

            if (IsForeignMetaObject(callArgs.MetaTarget) && (interopBinding = InteropBind(metaBuilder, callArgs)) != null)
            {
                return(interopBinding);
            }

            Build(metaBuilder, callArgs, true);
            return(metaBuilder.CreateMetaObject(this));
        }
Esempio n. 18
0
        private static bool IsFailureCached(Type /*!*/ type, string /*!*/ methodName)
        {
            // check for cached lookup failure (if the cache is available):
            bool result = false;
            var  cache  = Interlocked.Exchange(ref _clrFailedMemberLookupCache, null);

            if (cache != null)
            {
                result = cache.ContainsKey(new MemberLookupCacheEntry(type, methodName));
                Interlocked.Exchange(ref _clrFailedMemberLookupCache, cache);
            }

#if DEBUG
            PerfTrack.NoteEvent(PerfTrack.Categories.Count, "CLR member lookup failure cache " + (result ? "hit" : "miss"));
#endif
            return(result);
        }
Esempio n. 19
0
        internal static bool TryInvokeTernaryOperator(CodeContext context, object o, object arg1, object arg2, string name, out object value)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Temporary, "TernaryOp " + CompilerHelpers.GetType(o).Name + " " + name);

            PythonTypeSlot pts;
            PythonType     pt = DynamicHelpers.GetPythonType(o);
            object         callable;

            if (pt.TryResolveSlot(context, name, out pts) &&
                pts.TryGetValue(context, o, pt, out callable))
            {
                value = PythonCalls.Call(context, callable, arg1, arg2);
                return(true);
            }

            value = null;
            return(false);
        }
Esempio n. 20
0
        public object CallReflected(CodeContext context, object[] args)
        {
#if FULL
            if (ScriptDomainManager.Options.EngineDebug)
            {
                PerfTrack.NoteEvent(PerfTrack.Categories.Methods, this);
            }
#endif


            object   instance = _instanceBuilder.Build(context, args);
            object[] callArgs = new object[_argBuilders.Count];
            for (int i = 0; i < callArgs.Length; i++)
            {
                callArgs[i] = _argBuilders[i].Build(context, args);
            }

            object result;
            try {
                if (Method is ConstructorInfo)
                {
                    result = ((ConstructorInfo)Method).Invoke(callArgs);
                }
                else
                {
                    result = Method.Invoke(instance, callArgs);
                }
#if SILVERLIGHT && DEBUG // TODO: drop when Silverlight gets fixed
            } catch (System.Security.SecurityException) {
                throw new System.Security.SecurityException(String.Format("Access to method '{0}' denied.",
                                                                          ReflectionUtils.FormatSignature(new System.Text.StringBuilder(), Method)));
#endif
            } catch (TargetInvocationException tie) {
                throw tie.InnerException;
            }

            //This is only used to support explicit Reference arguments
            for (int i = 0; i < callArgs.Length; i++)
            {
                _argBuilders[i].UpdateFromReturn(callArgs[i], args);
            }

            return(_returnBuilder.Build(context, callArgs, args, result));
        }
Esempio n. 21
0
        internal DelegateInfo GenerateDelegateStub()
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.DelegateCreate, ToString());

            Type[] delegateParams = new Type[_parameters.Length];
            for (int i = 0; i < _parameters.Length; i++)
            {
                delegateParams[i] = _parameters[i].ParameterType;
            }

            // Create the method
            DynamicILGen cg = Snippets.Shared.CreateDynamicMethod(ToString(), _returnType, ArrayUtils.Insert(typeof(object[]), delegateParams), false);

            // Emit the stub
            object[] constants = EmitClrCallStub(cg);

            // Save the constants in the delegate info class
            return(new DelegateInfo(cg.Finish(), constants));
        }
Esempio n. 22
0
        internal T /*!*/ CreateDelegate <T>(Expression /*!*/ binding, int compilationThreshold) where T : class
        {
            Delegate d      = Stitch <T>(binding).LightCompile(compilationThreshold);
            T        result = (T)(object)d;

            LightLambda lambda = d.Target as LightLambda;

            if (lambda != null)
            {
                _rule           = result;
                lambda.Compile += (_, e) => _compiled = e.Compiled;
                return((T)GetInterpretingDelegate());
            }
            else
            {
                PerfTrack.NoteEvent(PerfTrack.Categories.Rules, "Rule not interpreted");
                return(result);
            }
        }
        public override DynamicMetaObject /*!*/ BindSetMember(SetMemberBinder /*!*/ member, DynamicMetaObject /*!*/ value)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Type SetMember " + Value.UnderlyingSystemType.FullName);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Type SetMember");
            PythonContext state = PythonContext.GetPythonContext(member);

            if (Value.IsSystemType)
            {
                MemberTracker tt = MemberTracker.FromMemberInfo(Value.UnderlyingSystemType);
                MemberGroup   mg = state.Binder.GetMember(MemberRequestKind.Set, Value.UnderlyingSystemType, member.Name);

                // filter protected member access against .NET types, these can only be accessed from derived types...
                foreach (MemberTracker mt in mg)
                {
                    if (IsProtectedSetter(mt))
                    {
                        return(new DynamicMetaObject(
                                   BindingHelpers.TypeErrorForProtectedMember(Value.UnderlyingSystemType, member.Name),
                                   Restrictions.Merge(value.Restrictions).Merge(BindingRestrictions.GetInstanceRestriction(Expression, Value))
                                   ));
                    }
                }

                // have the default binder perform it's operation against a TypeTracker and then
                // replace the test w/ our own.
                return(new DynamicMetaObject(
                           state.Binder.SetMember(
                               member.Name,
                               new DynamicMetaObject(
                                   AstUtils.Constant(tt),
                                   BindingRestrictions.Empty,
                                   tt
                                   ),
                               value,
                               new PythonOverloadResolverFactory(state.Binder, AstUtils.Constant(state.SharedContext))
                               ).Expression,
                           Restrictions.Merge(value.Restrictions).Merge(BindingRestrictions.GetInstanceRestriction(Expression, Value))
                           ));
            }

            return(MakeSetMember(member, value));
        }
        static InstructionList()
        {
            AppDomain.CurrentDomain.ProcessExit += new EventHandler((_, __) => {
                PerfTrack.DumpHistogram(_executedInstructions);
                Console.WriteLine("-- Total executed: {0}", _executedInstructions.Values.Aggregate(0, (sum, value) => sum + value));
                Console.WriteLine("-----");

                var referenced = new Dictionary <string, int>();
                int total      = 0;
                foreach (var entry in _instances)
                {
                    referenced[entry.Key] = entry.Value.Count;
                    total += entry.Value.Count;
                }

                PerfTrack.DumpHistogram(referenced);
                Console.WriteLine("-- Total referenced: {0}", total);
                Console.WriteLine("-----");
            });
        }
Esempio n. 25
0
        private DynamicMetaObject/*!*/ InvokeWorker(DynamicMetaObjectBinder/*!*/ call, Expression/*!*/ codeContext, DynamicMetaObject/*!*/[]/*!*/ args) {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "BuiltinFunc Invoke " + Value.DeclaringType.FullName + "." + Value.Name + " with " + args.Length + " args " + Value.IsUnbound);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "BuiltinFunction " + Value.Targets.Count + ", " + Value.Targets[0].GetParameters().Length);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "BuiltinFunction " + BindingHelpers.GetCallSignature(call));

            if (this.NeedsDeferral()) {
                return call.Defer(ArrayUtils.Insert(this, args));
            }

            for (int i = 0; i < args.Length; i++) {
                if (args[i].NeedsDeferral()) {
                    return call.Defer(ArrayUtils.Insert(this, args));
                }
            }

            if (Value.IsUnbound) {
                return MakeSelflessCall(call, codeContext, args);
            } else {
                return MakeSelfCall(call, codeContext, args);
            }
        }
Esempio n. 26
0
        /// <summary>
        /// Create a compiled delegate for the LightLambda, and saves it so
        /// future calls to Run will execute the compiled code instead of
        /// interpreting.
        /// </summary>
        internal void Compile(object state)
        {
            if (_compiled != null)
            {
                return;
            }

            // Compilation is expensive, we only want to do it once.
            lock (_compileLock) {
                if (_compiled != null)
                {
                    return;
                }

                PerfTrack.NoteEvent(PerfTrack.Categories.Compiler, "Interpreted lambda compiled");

                // Interpreter needs a standard delegate type.
                // So change the lambda's delegate type to Func<...> or
                // Action<...> so it can be called from the LightLambda.Run
                // methods.
                LambdaExpression lambda = (_lambda as LambdaExpression) ?? (LambdaExpression)((LightLambdaExpression)_lambda).Reduce();
                if (_interpreter != null)
                {
                    _compiledDelegateType = GetFuncOrAction(lambda);
                    lambda = Expression.Lambda(_compiledDelegateType, lambda.Body, lambda.Name, lambda.Parameters);
                }

                if (HasClosure)
                {
                    _compiled = LightLambdaClosureVisitor.BindLambda(lambda, _interpreter.ClosureVariables);
                }
                else
                {
                    _compiled = lambda.Compile();
                }
            }
        }
Esempio n. 27
0
        //TODO enable sharing of these custom delegates
        private Delegate CreateCustomDelegate(Type delegateType)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Compiler, "Synchronously compiling a custom delegate");

            var method             = delegateType.GetMethod("Invoke");
            var paramInfos         = method.GetParameters();
            var parameters         = new ParameterExpression[paramInfos.Length];
            var parametersAsObject = new Expression[paramInfos.Length];

            for (int i = 0; i < paramInfos.Length; i++)
            {
                ParameterExpression parameter = Expression.Parameter(paramInfos[i].ParameterType, paramInfos[i].Name);
                parameters[i]         = parameter;
                parametersAsObject[i] = Expression.Convert(parameter, typeof(object));
            }

            var data      = Expression.NewArrayInit(typeof(object), parametersAsObject);
            var self      = AstUtils.Constant(this);
            var runMethod = typeof(LightLambda).GetMethod("Run");
            var body      = Expression.Convert(Expression.Call(self, runMethod, data), method.ReturnType);
            var lambda    = Expression.Lambda(delegateType, body, parameters);

            return(lambda.Compile());
        }
Esempio n. 28
0
        public override T BindDelegate <T>(CallSite <T> site, object[] args)
        {
            //Debug.Assert(typeof(T).GetMethod("Invoke").ReturnType == Type);

            object target = args[0];
            T      res    = null;

            if (typeof(T) == typeof(Func <CallSite, object, string>) && target is string)
            {
                res = (T)(object)new Func <CallSite, object, string>(StringConversion);
            }
            else if (typeof(T) == typeof(Func <CallSite, object, int>))
            {
                if (target is int)
                {
                    res = (T)(object)new Func <CallSite, object, int>(IntConversion);
                }
                else if (target is bool)
                {
                    res = (T)(object)new Func <CallSite, object, int>(BoolToIntConversion);
                }
            }
            else if (typeof(T) == typeof(Func <CallSite, bool, int>))
            {
                res = (T)(object)new Func <CallSite, bool, int>(BoolToIntConversion);
            }
            else if (typeof(T) == typeof(Func <CallSite, object, bool>))
            {
                if (target is bool)
                {
                    res = (T)(object)new Func <CallSite, object, bool>(BoolConversion);
                }
                else if (target is string)
                {
                    res = (T)(object)new Func <CallSite, object, bool>(StringToBoolConversion);
                }
                else if (target is int)
                {
                    res = (T)(object)new Func <CallSite, object, bool>(IntToBoolConversion);
                }
                else if (target == null)
                {
                    res = (T)(object)new Func <CallSite, object, bool>(NullToBoolConversion);
                }
                else if (target.GetType() == typeof(object))
                {
                    res = (T)(object)new Func <CallSite, object, bool>(ObjectToBoolConversion);
                }
            }
            else if (target != null)
            {
                // Special cases:
                //  - string or bytes to IEnumerable or IEnumerator
                //  - CLR 4 only: BigInteger -> Complex
#if !CLR2
                if (target is BigInteger)
                {
                    if (typeof(T) == typeof(Func <CallSite, BigInteger, Complex>))
                    {
                        res = (T)(object)new Func <CallSite, BigInteger, Complex>(BigIntegerToComplexConversion);
                    }
                    else if (typeof(T) == typeof(Func <CallSite, object, Complex>))
                    {
                        res = (T)(object)new Func <CallSite, object, Complex>(BigIntegerObjectToComplexConversion);
                    }
                    else if (typeof(T) == typeof(Func <CallSite, BigInteger, object>))
                    {
                        res = (T)(object)new Func <CallSite, BigInteger, object>(BigIntegerToComplexObjectConversion);
                    }
                }
                else
#endif
                if (target is string)
                {
                    if (typeof(T) == typeof(Func <CallSite, string, IEnumerable>))
                    {
                        res = (T)(object)new Func <CallSite, string, IEnumerable>(StringToIEnumerableConversion);
                    }
                    else if (typeof(T) == typeof(Func <CallSite, string, IEnumerator>))
                    {
                        res = (T)(object)new Func <CallSite, string, IEnumerator>(StringToIEnumeratorConversion);
                    }
                    else if (typeof(T) == typeof(Func <CallSite, object, IEnumerable>))
                    {
                        res = (T)(object)new Func <CallSite, object, IEnumerable>(ObjectToIEnumerableConversion);
                    }
                    else if (typeof(T) == typeof(Func <CallSite, object, IEnumerator>))
                    {
                        res = (T)(object)new Func <CallSite, object, IEnumerator>(ObjectToIEnumeratorConversion);
                    }
                }
                else if (target.GetType() == typeof(Bytes))
                {
                    if (typeof(T) == typeof(Func <CallSite, Bytes, IEnumerable>))
                    {
                        res = (T)(object)new Func <CallSite, Bytes, IEnumerable>(BytesToIEnumerableConversion);
                    }
                    else if (typeof(T) == typeof(Func <CallSite, Bytes, IEnumerator>))
                    {
                        res = (T)(object)new Func <CallSite, Bytes, IEnumerator>(BytesToIEnumeratorConversion);
                    }
                    else if (typeof(T) == typeof(Func <CallSite, object, IEnumerable>))
                    {
                        res = (T)(object)new Func <CallSite, object, IEnumerable>(ObjectToIEnumerableConversion);
                    }
                    else if (typeof(T) == typeof(Func <CallSite, object, IEnumerator>))
                    {
                        res = (T)(object)new Func <CallSite, object, IEnumerator>(ObjectToIEnumeratorConversion);
                    }
                }

                if (res == null && (target.GetType() == Type || Type.IsAssignableFrom(target.GetType())))
                {
                    if (typeof(T) == typeof(Func <CallSite, object, object>))
                    {
                        // called via a helper call site in the runtime (e.g. Converter.Convert)
                        res = (T)(object)new Func <CallSite, object, object>(new IdentityConversion(target.GetType()).Convert);
                    }
                    else
                    {
                        // called via an embedded call site
                        Debug.Assert(typeof(T).GetMethod("Invoke").ReturnType == Type);
                        if (typeof(T).GetMethod("Invoke").GetParameters()[1].ParameterType == typeof(object))
                        {
                            object identityConversion = Activator.CreateInstance(typeof(IdentityConversion <>).MakeGenericType(Type), target.GetType());
                            res = (T)(object)Delegate.CreateDelegate(typeof(T), identityConversion, identityConversion.GetType().GetMethod("Convert"));
                        }
                    }
                }
            }

            if (res != null)
            {
                CacheTarget(res);
                return(res);
            }

            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Convert " + Type.FullName + " " + CompilerHelpers.GetType(args[0]) + " " + typeof(T));
            return(base.BindDelegate(site, args));
        }
Esempio n. 29
0
 public override DynamicMetaObject /*!*/ BindSetIndex(SetIndexBinder /*!*/ binder, DynamicMetaObject /*!*/[] /*!*/ indexes, DynamicMetaObject /*!*/ value)
 {
     PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass SetIndex" + indexes.Length);
     PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass SetIndex");
     return(PythonProtocol.Index(binder, PythonIndexType.SetItem, ArrayUtils.Insert(this, ArrayUtils.Append(indexes, value))));
 }
Esempio n. 30
0
 public override DynamicMetaObject /*!*/ BindUnaryOperation(UnaryOperationBinder /*!*/ binder)
 {
     PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass UnaryOperation" + binder.Operation);
     PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass UnaryOperation");
     return(PythonProtocol.Operation(binder, this, null));
 }