/// <summary> /// Creates and returns a MethodBuilder /// </summary> internal static MethodBuilder CompileLambda(LambdaExpression lambda, TypeBuilder type, MethodAttributes attributes, bool emitDebugSymbols) { // 1. Create signature List <Type> types; List <string> names; string lambdaName; Type returnType; ComputeSignature(lambda, out types, out names, out lambdaName, out returnType); // 2. Bind lambda AnalyzedTree tree = AnalyzeLambda(ref lambda); // 3. Create lambda compiler LambdaCompiler c = CreateStaticCompiler( tree, lambda, type, lambda.Name ?? "lambda_method", // don't use generated name attributes, returnType, types, names, false, // dynamicMethod emitDebugSymbols ); // 4. Emit c.EmitLambdaBody(null); return((MethodBuilder)c._method); }
private void EmitInlinedInvoke(InvocationExpression invoke, CompilationFlags flags) { LambdaExpression lambda = invoke.LambdaOperand; // This is tricky: we need to emit the arguments outside of the // scope, but set them inside the scope. Fortunately, using the IL // stack it is entirely doable. // 1. Emit invoke arguments List <WriteBack> wb = EmitArguments(lambda.Type.GetInvokeMethod(), invoke); // 2. Create the nested LambdaCompiler var inner = new LambdaCompiler(this, lambda, invoke); // 3. Emit the body // if the inlined lambda is the last expression of the whole lambda, // tail call can be applied. if (wb != null) { Debug.Assert(wb.Count > 0); flags = UpdateEmitAsTailCallFlag(flags, CompilationFlags.EmitAsNoTail); } inner.EmitLambdaBody(_scope, true, flags); // 4. Emit write-backs if needed EmitWriteBack(wb); }
/// <summary> /// Mutates the MethodBuilder parameter, filling in IL, parameters, /// and return type. /// /// (probably shouldn't be modifying parameters/return type...) /// </summary> internal static void Compile(LambdaExpression lambda, MethodBuilder method) { // 1. Bind lambda AnalyzedTree tree = AnalyzeLambda(ref lambda); // 2. Create lambda compiler LambdaCompiler c = new LambdaCompiler(tree, lambda, method); // 3. Emit c.EmitLambdaBody(); }
/// <summary> /// Compiler entry point /// </summary> /// <param name="lambda">LambdaExpression to compile.</param> /// <returns>The compiled delegate.</returns> internal static Delegate Compile(LambdaExpression lambda) { // 1. Bind lambda var tree = AnalyzeLambda(ref lambda); // 2. Create lambda compiler var c = new LambdaCompiler(tree, lambda); // 3. Emit c.EmitLambdaBody(); // 4. Return the delegate. return(c.CreateDelegate()); }
/// <summary> /// Compiler entry point /// </summary> /// <param name="lambda">LambdaExpression to compile.</param> /// <returns>The compiled delegate.</returns> internal static Delegate Compile(LambdaExpression lambda) { lambda.ValidateArgumentCount(); // 1. Bind lambda AnalyzedTree tree = AnalyzeLambda(ref lambda); // 2. Create lambda compiler LambdaCompiler c = new LambdaCompiler(tree, lambda); // 3. Emit c.EmitLambdaBody(); // 4. Return the delegate. return(c.CreateDelegate()); }
/// <summary> /// Compiler entry point /// </summary> /// <param name="lambda">LambdaExpression to compile.</param> /// <param name="method">Product of compilation</param> /// <param name="delegateType">Type of the delegate to create</param> /// <param name="emitDebugSymbols">True to emit debug symbols, false otherwise.</param> /// <param name="forceDynamic">Force dynamic method regardless of save assemblies.</param> /// <returns>The compiled delegate.</returns> internal static Delegate CompileLambda(LambdaExpression lambda, Type delegateType, bool emitDebugSymbols, bool forceDynamic, out MethodInfo method) { // 1. Create signature List <Type> types; List <string> names; string name; Type returnType; ComputeSignature(lambda, out types, out names, out name, out returnType); // 2. Bind lambda AnalyzedTree tree = AnalyzeLambda(ref lambda); // 3. Create lambda compiler LambdaCompiler c = CreateDynamicCompiler(tree, lambda, name, returnType, types, null, emitDebugSymbols, forceDynamic); // 4. Emit c.EmitLambdaBody(null); // 5. Return the delegate. return(c.CreateDelegate(delegateType, out method)); }
private void EmitInlinedInvoke(InvocationExpression invoke, CompilationFlags flags) { var lambda = invoke.LambdaOperand; // This is tricky: we need to emit the arguments outside of the // scope, but set them inside the scope. Fortunately, using the IL // stack it is entirely doable. // 1. Emit invoke arguments List<WriteBack> wb = EmitArguments(lambda.Type.GetMethod("Invoke"), invoke); // 2. Create the nested LambdaCompiler var inner = new LambdaCompiler(this, lambda, invoke); // 3. Emit the body // if the inlined lambda is the last expression of the whole lambda, // tail call can be applied. if (wb.Count != 0) { flags = UpdateEmitAsTailCallFlag(flags, CompilationFlags.EmitAsNoTail); } inner.EmitLambdaBody(_scope, true, flags); // 4. Emit write-backs if needed EmitWriteBack(wb); }
private void EmitInlinedInvoke(InvocationExpression invoke) { var lambda = invoke.LambdaOperand; // This is tricky: we need to emit the arguments outside of the // scope, but set them inside the scope. Fortunately, using the IL // stack it is entirely doable. // 1. Emit invoke arguments List<WriteBack> wb = EmitArguments(lambda.Type.GetMethod("Invoke"), invoke); // 2. Create the nested LambdaCompiler var inner = new LambdaCompiler(this, lambda); // 3. Emit the body inner.EmitLambdaBody(_scope, true); // 4. Emit writebacks if needed EmitWriteBack(wb); }