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(); }
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)); }
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); }
public override System.Linq.Expressions.Expression TransformRead() { var args = TransformTargetAndArguments(); return(System.Linq.Expressions.Expression.Dynamic(LanguageContext.CreateInvokeBinder(args.Item2), typeof(object), args.Item1)); }
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); }
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(); }