private void EmitSyncCall(List<ParameterInfo> parameters, EmitHelper emit) { Context.MethodBuilder.MethodBuilder.SetCustomAttribute(_soapDocumentAttributeBuilder); bool withOutParameters = EmitParameters(emit, parameters); bool callGeneric = !withOutParameters && Context.CurrentMethod.ReturnType != typeof(void); // Use Invoke<T>() for methods with return value but // Invoke() for methods with no return value or with out/ref parameters. // MethodInfo invoke = TypeHelper.GetMethod( typeof(WebClientBase), callGeneric, "Invoke", BindingFlags.Public | BindingFlags.Instance); if (callGeneric) { emit .call (invoke.MakeGenericMethod(Context.CurrentMethod.ReturnType)) .stloc (Context.ReturnValue) ; } else { if (withOutParameters) { LocalBuilder ret = emit.DeclareLocal(typeof(object[])); Label exit = emit.DefineLabel(); emit .call (invoke) .dup .stloc (ret) .brfalse_s (exit) ; int idx = 0; if (Context.CurrentMethod.ReturnType != typeof(void)) { emit .ldloc (ret) .ldc_i4_0 .ldelem_ref .CastFromObject (Context.CurrentMethod.ReturnType) .stloc (Context.ReturnValue) ; ++idx; } for (int i = 0; i < parameters.Count; ++i) { ParameterInfo pi = parameters[i]; Type type = pi.ParameterType; if (!type.IsByRef) continue; // Get ride of ref // type = type.GetElementType(); emit .ldarg (pi) .ldloc (ret) .ldc_i4_ (idx) .ldelem_ref .CastFromObject (type) .stind (type) ; ++idx; } emit.MarkLabel(exit); } else { emit .call (invoke) .pop .end () ; } } }
private void EmitAsyncCall(List<ParameterInfo> parameters, EmitHelper emit, ParameterInfo callback, ParameterInfo exceptionCallback) { if (Context.CurrentMethod.IsDefined(typeof(UpToDateAttribute), true)) { EmitCookie(emit); } else { emit.ldnull.end(); } if (exceptionCallback != null) { emit.ldarg(exceptionCallback); } else { emit.ldnull.end(); } emit.ldarg(callback); EmitParameters(emit, parameters); emit .call(typeof(WebClientBase), "InvokeAsync", typeof(string), typeof(AsyncCallState), typeof(Action<Exception>), typeof(Delegate), typeof(object[])) ; }