/// <summary> /// Creates a lambda compiler that will compile to a dynamic method /// </summary> private LambdaCompiler(AnalyzedTree tree, LambdaExpression lambda) { var parameterTypes = GetParameterTypes(lambda).AddFirst(typeof(Closure)); var method = new DynamicMethod(lambda.Name ?? "lambda_method", lambda.ReturnType, parameterTypes, true); _tree = tree; _lambda = lambda; _method = method; // In a Win8 immersive process user code is not allowed to access non-W8P framework APIs through // reflection or RefEmit. Framework code, however, is given an exemption. // This is to make sure that user code cannot access non-W8P framework APIs via ExpressionTree. // TODO: This API is not available, is there an alternative way to achieve the same. // method.ProfileAPICheck = true; _ilg = method.GetILGenerator(); _hasClosureArgument = true; // These are populated by AnalyzeTree/VariableBinder _scope = tree.Scopes[lambda]; _boundConstants = tree.Constants[lambda]; InitializeMethod(); }
/// <summary> /// Creates a lambda compiler that will compile into the provided Methodbuilder /// </summary> private LambdaCompiler(AnalyzedTree tree, LambdaExpression lambda, MethodBuilder method) { _hasClosureArgument = tree.Scopes[lambda].NeedsClosure; var paramTypes = GetParameterTypes(lambda); if (_hasClosureArgument) { paramTypes = paramTypes.AddFirst(typeof(Closure)); } method.SetReturnType(lambda.ReturnType); method.SetParameters(paramTypes); var paramNames = lambda.Parameters.Map(p => p.Name); // parameters are index from 1, with closure argument we need to skip the first arg var startIndex = _hasClosureArgument ? 2 : 1; for (int i = 0; i < paramNames.Length; i++) { method.DefineParameter(i + startIndex, ParameterAttributes.None, paramNames[i]); } _tree = tree; _lambda = lambda; _typeBuilder = (TypeBuilder)method.DeclaringType; _method = method; _ilg = method.GetILGenerator(); // These are populated by AnalyzeTree/VariableBinder _scope = tree.Scopes[lambda]; _boundConstants = tree.Constants[lambda]; InitializeMethod(); }
/// <summary> /// Creates a lambda compiler for an inlined lambda /// </summary> private LambdaCompiler(LambdaCompiler parent, LambdaExpression lambda) { _tree = parent._tree; _lambda = lambda; _method = parent._method; _ilg = parent._ilg; _hasClosureArgument = parent._hasClosureArgument; _typeBuilder = parent._typeBuilder; _scope = _tree.Scopes[lambda]; _boundConstants = parent._boundConstants; }