예제 #1
0
        internal DelegateInfo(LanguageContext context, Type returnType, ParameterInfo[] parameters) {
            Assert.NotNull(returnType);
            Assert.NotNullItems(parameters);

            _returnType = returnType;
            _parameters = parameters;

            PerfTrack.NoteEvent(PerfTrack.Categories.DelegateCreate, ToString());

            if (_returnType != typeof(void)) {
                _convertBinder = context.CreateConvertBinder(_returnType, true);
            }

            _invokeBinder = context.CreateInvokeBinder(new CallInfo(_parameters.Length));

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

            // Create the method with a special name so the langauge compiler knows that method's stack frame is not visible
            DynamicILGen cg = Snippets.Shared.CreateDynamicMethod("_Scripting_", _returnType, ArrayUtils.Insert(typeof(object[]), delegateParams), false);

            // Emit the stub
            _constants = EmitClrCallStub(cg);
            _method = cg.Finish();
        }
예제 #2
0
        internal DelegateSignatureInfo(LanguageContext context, Type returnType, ParameterInfo[] parameters) {
            Assert.NotNull(context, returnType);
            Assert.NotNullItems(parameters);

            _context = context;
            _parameters = parameters;
            _returnType = returnType;
            
            if (_returnType != typeof(void)) {
                _convert = _context.CreateConvertBinder(_returnType, true);
            }
            
            _invoke = _context.CreateInvokeBinder(new CallInfo(_parameters.Length));
        }
예제 #3
0
        internal DelegateSignatureInfo(LanguageContext context, Type returnType, ParameterInfo[] parameters) {
            Assert.NotNull(context, returnType);
            Assert.NotNullItems(parameters);

            _context = context;
            _parameters = parameters;
            _returnType = returnType;
            
            if (_returnType != typeof(void)) {
                _convert = _context.CreateConvertBinder(_returnType, true);
            }
            
            ArgumentInfo[] args = new ArgumentInfo[_parameters.Length];
            for (int i = 0; i < args.Length; i++) {
                args[i] = Expression.PositionalArg(i);
            }

            _invoke = _context.CreateInvokeBinder(args);
        }
예제 #4
0
        public override System.Linq.Expressions.Expression TransformRead()
        {
            var args = TransformTargetAndArguments();

            return(System.Linq.Expressions.Expression.Dynamic(LanguageContext.CreateInvokeBinder(args.Item2), typeof(object), args.Item1));
        }
예제 #5
0
        public DelegateInfo(LanguageContext context, Type returnType, Type[] parameters)
        {
            Assert.NotNull(returnType);
            Assert.NotNullItems(parameters);

            _returnType = returnType;
            _parameterTypes = parameters;

            PerfTrack.NoteEvent(PerfTrack.Categories.DelegateCreate, ToString());

            if (_returnType != typeof(void)) {
                _convertBinder = context.CreateConvertBinder(_returnType, true);
            }

            _invokeBinder = context.CreateInvokeBinder(new CallInfo(_parameterTypes.Length));

            Type[] delegateParams = new Type[1 + _parameterTypes.Length];
            delegateParams[0] = typeof(object[]);
            for (int i = 0; i < _parameterTypes.Length; i++) {
                delegateParams[1 + i] = _parameterTypes[i];
            }

            EmitClrCallStub(returnType, delegateParams, out _method);
        }
예제 #6
0
        internal static Delegate CreateDelegateForDynamicObject(LanguageContext context, object dynamicObject, Type delegateType, MethodInfo invoke)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.DelegateCreate, delegateType.ToString());

            Type returnType = invoke.ReturnType;
            ParameterInfo[] parameterInfos = invoke.GetParameters();

            var parameters = new List<ParameterExpression>();
            for (int i = 0; i < parameterInfos.Length; i++) {
                parameters.Add(Expression.Parameter(parameterInfos[i].ParameterType, "p" + i));
            }

            InvokeBinder invokeBinder = context.CreateInvokeBinder(new CallInfo(parameterInfos.Length));
            ConvertBinder convertBinder = (returnType != typeof(void)) ? context.CreateConvertBinder(returnType, explicitCast: true) : null;

            CallSite invokeSite = CallSite.Create(DynamicSiteHelpers.MakeCallSiteDelegate(MakeSiteSignature(parameterInfos)), invokeBinder);
            Type invokeSiteType = invokeSite.GetType();

            Type convertSiteType;
            CallSite convertSite;
            if (convertBinder != null) {
                convertSite = CallSite.Create(DynamicSiteHelpers.MakeCallSiteDelegate(typeof(object), returnType), convertBinder);
                convertSiteType = convertSite.GetType();
            } else {
                convertSiteType = null;
                convertSite = null;
            }

            var locals = new List<ParameterExpression>();

            ParameterExpression invokeSiteVar = Expression.Parameter(invokeSiteType, "site");
            ParameterExpression convertSiteVar = null;

            var args = new List<Expression>();
            args.Add(invokeSiteVar);
            args.Add(Expression.Constant(dynamicObject));

            int strongBoxVarsStart = locals.Count;

            for (int i = 0; i < parameterInfos.Length; i++) {
                if (parameterInfos[i].ParameterType.IsByRef) {
                    var argType = parameterInfos[i].ParameterType;

                    Type elementType = argType.GetElementType();
                    Type concreteType = typeof(StrongBox<>).MakeGenericType(elementType);

                    var strongBox = Expression.Parameter(concreteType, "box" + i);
                    locals.Add(strongBox);

                    args.Add(
                        Expression.Assign(
                            strongBox,
                            Expression.New(
                                concreteType.GetConstructor(new Type[] { elementType }),
                                parameters[i]
                            )
                        )
                    );

                } else {
                    args.Add(parameters[i]);
                }
            }

            int strongBoxVarsEnd = locals.Count;

            Expression invocation = Expression.Invoke(
                Expression.Field(
                    Expression.Assign(
                        invokeSiteVar,
                        Expression.Convert(Expression.Constant(invokeSite), invokeSiteType)
                    ),
                    invokeSiteType.GetDeclaredField("Target")
                ),
                args
            );

            if (convertBinder != null) {
                convertSiteVar = Expression.Parameter(convertSiteType, "convertSite");

                invocation = Expression.Invoke(
                    Expression.Field(
                        Expression.Assign(
                            convertSiteVar,
                            Expression.Convert(Expression.Constant(convertSite), convertSiteType)
                        ),
                        convertSiteType.GetDeclaredField("Target")
                    ),
                    convertSiteVar,
                    invocation
                );
            }

            locals.Add(invokeSiteVar);
            if (convertSiteVar != null) {
                locals.Add(convertSiteVar);
            }

            Expression body;

            // copy back from StrongBox.Value
            if (strongBoxVarsEnd > strongBoxVarsStart) {
                var block = new Expression[1 + strongBoxVarsEnd - strongBoxVarsStart + 1];

                var resultVar = Expression.Parameter(invocation.Type, "result");
                locals.Add(resultVar);

                int b = 0;
                int l = strongBoxVarsStart;

                // values of strong boxes are initialized in invocation expression:
                block[b++] = Expression.Assign(resultVar, invocation);

                for (int i = 0; i < parameterInfos.Length; i++) {
                    if (parameterInfos[i].ParameterType.IsByRef) {
                        var local = locals[l++];
                        block[b++] = Expression.Assign(
                            parameters[i],
                            Expression.Field(local, local.Type.GetDeclaredField("Value"))
                        );
                    }
                }

                block[b++] = resultVar;

                Debug.Assert(l == strongBoxVarsEnd);
                Debug.Assert(b == block.Length);

                body = Expression.Block(locals, block);
            } else {
                body = Expression.Block(locals, invocation);
            }

            var lambda = Expression.Lambda(delegateType, body, "_Scripting_", parameters);
            return lambda.Compile();
        }