//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]; bool hasByRef = false; for (int i = 0; i < paramInfos.Length; i++) { ParameterExpression parameter = Expression.Parameter(paramInfos[i].ParameterType, paramInfos[i].Name); hasByRef = hasByRef || paramInfos[i].ParameterType.IsByRef; parameters[i] = parameter; parametersAsObject[i] = Expression.Convert(parameter, typeof(object)); } var data = Expression.NewArrayInit(typeof(object), parametersAsObject); var dlg = new Func <object[], object>(Run); var dlgExpr = AstUtils.Constant(dlg); var argsParam = Expression.Parameter(typeof(object[]), "$args"); Expression body; if (method.ReturnType == typeof(void)) { body = Expression.Block(typeof(void), Expression.Invoke(dlgExpr, argsParam)); } else { body = Expression.Convert(Expression.Invoke(dlgExpr, argsParam), method.ReturnType); } if (hasByRef) { List <Expression> updates = new List <Expression>(); for (int i = 0; i < paramInfos.Length; i++) { if (paramInfos[i].ParameterType.IsByRef) { updates.Add( Expression.Assign( parameters[i], Expression.Convert( Expression.ArrayAccess(argsParam, Expression.Constant(i)), paramInfos[i].ParameterType.GetElementType() ) ) ); } } body = Expression.TryFinally(body, Expression.Block(typeof(void), updates)); } body = Expression.Block( method.ReturnType, new[] { argsParam }, Expression.Assign(argsParam, data), body ); var lambda = Expression.Lambda(delegateType, body, parameters); //return System.Linq.Expressions.Compiler.LambdaCompiler.Compile(lambda, null); throw new NotImplementedException("byref delegate"); }
internal virtual Expression GetFalse() { // Using a singleton here to ensure a stable object identity for IfFalse, which Update relies on. return(AstUtils.Empty()); }