/// <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 that will compile into the provided MethodBuilder /// </summary> private LambdaCompiler(AnalyzedTree tree, LambdaExpression lambda, MethodBuilder method) { var scope = tree.Scopes[lambda]; var hasClosureArgument = scope.NeedsClosure; Type[] paramTypes = GetParameterTypes(lambda, hasClosureArgument ? typeof(Closure) : null); method.SetReturnType(lambda.ReturnType); method.SetParameters(paramTypes); var parameters = lambda.Parameters; // parameters are index from 1, with closure argument we need to skip the first arg int startIndex = hasClosureArgument ? 2 : 1; for (int i = 0, n = parameters.Count; i < n; i++) { method.DefineParameter(i + startIndex, ParameterAttributes.None, parameters[i].Name); } _tree = tree; _lambda = lambda; _typeBuilder = (TypeBuilder)method.DeclaringType; _method = method; _hasClosureArgument = hasClosureArgument; _ilg = method.GetILGenerator(); // These are populated by AnalyzeTree/VariableBinder _scope = scope; _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; }
protected internal override Expression VisitLambda <T>(Expression <T> node) { CompilerScope scope; BoundConstants constants; this._tree.Scopes[node] = scope = new CompilerScope(node, true); this._scopes.Push(scope); this._tree.Constants[node] = constants = new BoundConstants(); this._constants.Push(constants); base.Visit(this.MergeScopes(node)); this._constants.Pop(); this._scopes.Pop(); return(node); }
/// <summary> /// Creates a lambda compiler for an inlined lambda /// </summary> private LambdaCompiler( LambdaCompiler parent, LambdaExpression lambda, InvocationExpression invocation) { _tree = parent._tree; _lambda = lambda; _method = parent._method; _ilg = parent._ilg; _hasClosureArgument = parent._hasClosureArgument; _typeBuilder = parent._typeBuilder; // inlined scopes are associated with invocation, not with the lambda _scope = _tree.Scopes[invocation]; _boundConstants = parent._boundConstants; }
protected internal override Expression VisitLambda <T>(Expression <T> node) { var createdScope = new CompilerScope(node, true); _tree.Scopes[node] = createdScope; _scopes.Push(createdScope); var createdConstants = new BoundConstants(); _tree.Constants[node] = createdConstants; _constants.Push(createdConstants); Visit(MergeScopes(node)); _constants.Pop(); _scopes.Pop(); return(node); }
/// <summary> /// Creates a lambda compiler that will compile to a dynamic method /// </summary> private LambdaCompiler(AnalyzedTree tree, LambdaExpression lambda) { Type[] parameterTypes = GetParameterTypes(lambda, typeof(Closure)); var method = new DynamicMethod(lambda.Name ?? "lambda_method", lambda.ReturnType, parameterTypes, true); _tree = tree; _lambda = lambda; _method = method; _ilg = method.GetILGenerator(); _hasClosureArgument = true; // These are populated by AnalyzeTree/VariableBinder _scope = tree.Scopes[lambda]; _boundConstants = tree.Constants[lambda]; InitializeMethod(); }
private LambdaCompiler( AnalyzedTree tree, LambdaExpression lambda, TypeBuilder typeBuilder, MethodInfo method, ILGenerator ilg, IList <Type> paramTypes, bool dynamicMethod, bool emitDebugSymbols) { ContractUtils.Requires(dynamicMethod || method.IsStatic, "dynamicMethod"); _tree = tree; _lambda = lambda; _typeBuilder = typeBuilder; _method = method; _paramTypes = new ReadOnlyCollection <Type>(paramTypes); _dynamicMethod = dynamicMethod; // These are populated by AnalyzeTree/VariableBinder _scope = tree.Scopes[lambda]; _boundConstants = tree.Constants[lambda]; if (!dynamicMethod && _boundConstants.Count > 0) { throw Error.RtConstRequiresBundDelegate(); } _ilg = new ILGen(ilg); Debug.Assert(!emitDebugSymbols || _typeBuilder != null, "emitting debug symbols requires a TypeBuilder"); _emitDebugSymbols = emitDebugSymbols; // See if we can find a return label, so we can emit better IL AddReturnLabel(_lambda.Body); _boundConstants.EmitCacheConstants(this); }