public static AddDebugInfo ( Expression expr, IPersistentMap spanMap ) : Expression | ||
expr | Expression | |
spanMap | IPersistentMap | |
Результат | Expression |
static public void EmitDynamicCallPreamble(DynamicExpression dyn, IPersistentMap spanMap, string methodName, Type returnType, List <ParameterExpression> paramExprs, Type[] paramTypes, CljILGen ilg, out LambdaExpression lambda, out Type delType, out MethodBuilder mbLambda) { Expression call = dyn; GenContext context = Compiler.CompilerContextVar.deref() as GenContext; if (context != null && context.DynInitHelper != null) { call = context.DynInitHelper.ReduceDyn(dyn); } if (returnType == typeof(void)) { call = Expression.Block(call, Expression.Default(typeof(object))); returnType = typeof(object); } else if (returnType != call.Type) { call = Expression.Convert(call, returnType); } call = GenContext.AddDebugInfo(call, spanMap); delType = Microsoft.Scripting.Generation.Snippets.Shared.DefineDelegate("__interop__", returnType, paramTypes); lambda = Expression.Lambda(delType, call, paramExprs); mbLambda = null; if (context == null) { // light compile Delegate d = lambda.Compile(); int key = RT.nextID(); CacheDelegate(key, d); ilg.EmitInt(key); ilg.Emit(OpCodes.Call, Method_MethodExpr_GetDelegate); ilg.Emit(OpCodes.Castclass, delType); } else { mbLambda = context.TB.DefineMethod(methodName, MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes); lambda.CompileToMethod(mbLambda); } }
static public void EmitDynamicCallPreamble(DynamicExpression dyn, IPersistentMap spanMap, string methodName, Type returnType, IList <ParameterExpression> paramExprs, Type[] paramTypes, CljILGen ilg, out LambdaExpression lambda, out Type delType, out MethodBuilder mbLambda) { Expression call = dyn; GenContext context = Compiler.CompilerContextVar.deref() as GenContext; DynInitHelper.SiteInfo siteInfo; if (context != null && context.DynInitHelper != null) { call = context.DynInitHelper.ReduceDyn(dyn, out siteInfo); } else { throw new InvalidOperationException("Don't know how to handle callsite in this case"); } if (returnType == typeof(void)) { call = Expression.Block(call, Expression.Default(typeof(object))); returnType = typeof(object); } else if (returnType != call.Type) { call = Expression.Convert(call, returnType); } call = GenContext.AddDebugInfo(call, spanMap); delType = Microsoft.Scripting.Generation.Snippets.Shared.DefineDelegate("__interop__", returnType, paramTypes); lambda = Expression.Lambda(delType, call, paramExprs); mbLambda = null; if (context == null) { // light compile Delegate d = lambda.Compile(); int key = RT.nextID(); CacheDelegate(key, d); ilg.EmitInt(key); ilg.Emit(OpCodes.Call, Method_MethodExpr_GetDelegate); ilg.Emit(OpCodes.Castclass, delType); } else { mbLambda = context.TB.DefineMethod(methodName, MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes); //lambda.CompileToMethod(mbLambda); // Now we get to do all this code create by hand. // the primary code is // (loc1 = fb).Target.Invoke(loc1,*args); // if return type if void, pop the value and push a null // if return type does not match the call site, add a conversion CljILGen ilg2 = new CljILGen(mbLambda.GetILGenerator()); ilg2.EmitFieldGet(siteInfo.FieldBuilder); ilg2.Emit(OpCodes.Dup); LocalBuilder siteVar = ilg2.DeclareLocal(siteInfo.DelegateType); ilg2.Emit(OpCodes.Stloc, siteVar); ilg2.EmitFieldGet(siteInfo.SiteType.GetField("Target")); ilg2.Emit(OpCodes.Ldloc, siteVar); for (int i = 0; i < paramExprs.Count; i++) { ilg2.EmitLoadArg(i); } ilg2.EmitCall(siteInfo.DelegateType.GetMethod("Invoke")); if (returnType == typeof(void)) { ilg2.Emit(OpCodes.Pop); ilg2.EmitNull(); } else if (returnType != call.Type) { EmitConvertToType(ilg2, call.Type, returnType, false); } ilg2.Emit(OpCodes.Ret); /* * return Expression.Block( * new[] { site }, * Expression.Call( * Expression.Field( * Expression.Assign(site, access), * cs.GetType().GetField("Target") * ), * node.DelegateType.GetMethod("Invoke"), * ClrExtensions.ArrayInsert(site, node.Arguments) * ) */ } }