public DebugInfoCompileUnitEntry( DebugInfoGenerator debugInfoGenerator, ISourceFileEntry entry, CollectionMetadata file) { this.debugInfoGenerator = debugInfoGenerator; this.file = file; CollectionMetadata enumTypes; CollectionMetadata retainedTypes; CollectionMetadata subprograms; CollectionMetadata globalVariables; CollectionMetadata importedEntities; this.debugInfoGenerator.DefineCompilationUnit( this.file, out enumTypes, out retainedTypes, out subprograms, out globalVariables, out importedEntities); this.enumTypes = enumTypes; this.retainedTypes = retainedTypes; this.subprograms = subprograms; this.globalVariables = globalVariables; this.importedEntities = importedEntities; }
public DebugInfoSourceFileEntry(DebugInfoGenerator debugInfoGenerator, string directory, string fileName) { this.debugInfoGenerator = debugInfoGenerator; this.Directory = directory; this.FileName = fileName; this.file = this.debugInfoGenerator.DefineFile(this); }
public DebugInfoSourceMethodBuilder(DebugInfoGenerator debugInfoGenerator, ISourceMethod method, CollectionMetadata file, CollectionMetadata subprograms) { this.debugInfoGenerator = debugInfoGenerator; CollectionMetadata subroutineTypes; CollectionMetadata functionVariables; subprograms.Add(this.function = debugInfoGenerator.DefineMethod(method, file, out functionVariables)); this.functionVariables = functionVariables; }
/// <summary> /// Compiles the lambda into a method definition and custom debug information. /// </summary> /// <param name="method">A <see cref="MethodBuilder"/> which will be used to hold the lambda's IL.</param> /// <param name="debugInfoGenerator">Debugging information generator used by the compiler to mark sequence points and annotate local variables.</param> public void CompileToMethod(MethodBuilder method, DebugInfoGenerator debugInfoGenerator) { ContractUtils.RequiresNotNull(debugInfoGenerator, "debugInfoGenerator"); CompileToMethodInternal(method, debugInfoGenerator); }
/// <summary></summary> public Func <T, bool> Compile(DebugInfoGenerator debugInfoGenerator) { return(Predicate.Compile(debugInfoGenerator)); }
public IEnumerable <Func <HtmlElement, IEnumerable <HtmlElement> > > CreateHtmlFuncs(string htmlQueryString) { var elementParam = Expression.Parameter(typeof(HtmlElement), "HtmlQueryDomElement"); var keyValueParam = Expression.Parameter(typeof(KeyValuePair <string, IEnumerable <string> >), "HtmlQueryAttribute"); var valueParam = Expression.Parameter(typeof(string), "HtmlQueryAttributeValue"); var expressions = ParseHtmlQuery(elementParam, keyValueParam, valueParam, htmlQueryString); foreach (var expression in expressions) { var expression2 = expression.ToString().Contains("HtmlQueryAttribute") ? elementParam.CreateKeyValueAnyExpression( PredicateBuilder.EnumerableMethodName.Any, "Attributes", expression, keyValueParam) : expression; var ee = elementParam.CreateElementsWhereExpression <HtmlElement>( PredicateBuilder.EnumerableMethodName.Where, "Descendants", expression2); yield return(Expression.Lambda <Func <HtmlElement, IEnumerable <HtmlElement> > >(ee, new[] { elementParam }).Compile(DebugInfoGenerator.CreatePdbGenerator())); } }
public void TestMethod1() { //Expression<Func<IDictionary<string, IEnumerable<string>>, int>> test = attribute => attribute.Count; //Expression<Func<KeyValuePair<string, IEnumerable<string>>, int>> asdf = attribute => attribute.; //Expression<Func<IEnumerable<string>, int>> lfksjd = att => att.Count(); //var eParmkeyValueParm2 = Expression.Parameter(typeof(KeyValuePair<string, IEnumerable<string>>)); var eParm = Expression.Parameter(typeof(HtmlElement)); var a = eParm.CreateAnyExpression(); var elem = new HtmlElement { Descendants = new List <HtmlElement> { new HtmlElement { Attributes = new Dictionary <string, IEnumerable <string> > { { "id", new[] { "ID" } }, { "class", new[] { "CLASS" } } } } } }; var elem2 = new HtmlElement { Descendants = new List <HtmlElement> { new HtmlElement { Attributes = new Dictionary <string, IEnumerable <string> >() } } }; var elem3 = new HtmlElement { Descendants = new List <HtmlElement> { new HtmlElement() } }; var elem4 = new HtmlElement { Descendants = new List <HtmlElement>() }; var elem5 = new HtmlElement { Descendants = new List <HtmlElement> { new HtmlElement { Attributes = new Dictionary <string, IEnumerable <string> > { { "id", new[] { "class" } }, { "class", new[] { "id" } } } } } }; var keyValueParm = Expression.Parameter(typeof(KeyValuePair <string, IEnumerable <string> >)); var keyCompareExpression = keyValueParm.CreateStringPropertyCompareExpression( "class", "Key", PredicateBuilder.StringTransform.ToLowerInvariant, PredicateBuilder.StringComparison.Equals); var valueParm = Expression.Parameter(typeof(string)); var valueCompareExpression = keyValueParm.CreateStringPropertyCompareExpression( "class", valueParm, PredicateBuilder.StringTransform.ToLowerInvariant, PredicateBuilder.StringComparison.Equals); var valuesCompareExpression = keyValueParm.CreateKeyValueBoolExpression <string>( valueParm, valueCompareExpression, PredicateBuilder.EnumerableMethodName.Any); var attributesCompareExpression = Expression.AndAlso(keyCompareExpression, valuesCompareExpression); var parm = Expression.Parameter(typeof(HtmlElement)); var attributesAnyExpression = parm.CreateKeyValueAnyExpression( PredicateBuilder.EnumerableMethodName.Any, "Attributes", attributesCompareExpression, keyValueParm); var ee = parm.CreateElementsWhereExpression <HtmlElement>( PredicateBuilder.EnumerableMethodName.Where, "Descendants", attributesAnyExpression); var l = Expression.Lambda <Func <HtmlElement, IEnumerable <HtmlElement> > >(ee, new[] { parm }).Compile(DebugInfoGenerator.CreatePdbGenerator()); Assert.IsTrue(l(elem).Any()); Assert.IsFalse(l(elem2).Any()); //Assert.IsFalse(l(elem3).Any()); //Assert.IsFalse(l(elem4).Any()); Assert.IsFalse(l(elem5).Any()); }
public static T CompileToMethod <T>(Expression <T> lambda, DebugInfoGenerator debugInfoGenerator, bool emitDebugSymbols) { return((T)(object)CompileToMethod((LambdaExpression)lambda, debugInfoGenerator, emitDebugSymbols)); }
private static void CompileToMethodInternal(LambdaExpression lambda, MethodBuilder method, DebugInfoGenerator debugInfoGenerator, CompilerOptions options) { var compiledLambdas = new List <CompiledLambda>(); ParsedLambda parsedLambda; var module = method.Module as ModuleBuilder; if (module == null) { throw new ArgumentException("Unable to obtain module builder of the method", "method"); } method.SetReturnType(lambda.ReturnType); method.SetParameters(lambda.Parameters.Select(parameter => parameter.Type).ToArray()); var resolvedLambda = new ExpressionClosureResolver(lambda, module, false, options).Resolve(out parsedLambda); if (!string.IsNullOrEmpty(DebugOutputDirectory)) { resolvedLambda = AdvancedDebugViewWriter.WriteToModifying(resolvedLambda, parsedLambda.ConstantsType, parsedLambda.ConstantsParameter, parsedLambda.Constants, GenerateFileName(resolvedLambda)); } if (parsedLambda.ConstantsParameter != null) { throw new InvalidOperationException("Non-trivial constants are not allowed for compilation to method"); } CompileToMethodInternal(resolvedLambda, debugInfoGenerator, parsedLambda, options, compiledLambdas, method); }
public static Delegate Compile(LambdaExpression lambda, CompilerOptions options) { CheckLambdaParameters(lambda); CompiledLambda[] subLambdas; var debugInfoGenerator = string.IsNullOrEmpty(DebugOutputDirectory) ? null : DebugInfoGenerator.CreatePdbGenerator(); return(CompileInternal(lambda, debugInfoGenerator, out subLambdas, options)); }
/// <summary> /// Compiles the LambdaExpression. /// /// If the lambda is compiled with emitDebugSymbols, it will be /// generated into a TypeBuilder. Otherwise, this method is the same as /// calling LambdaExpression.Compile() /// /// This is a workaround for a CLR limitiation: DynamicMethods cannot /// have debugging information. /// </summary> /// <param name="lambda">the lambda to compile</param> /// <param name="emitDebugSymbols">true to generate a debuggable method, false otherwise</param> /// <returns>the compiled delegate</returns> public static T Compile <T>(this Expression <T> lambda, bool emitDebugSymbols) { return(emitDebugSymbols ? CompileToMethod(lambda, DebugInfoGenerator.CreatePdbGenerator(), true) : lambda.Compile()); }
public static Type Compile(Type inputElementType, params IFusionOperator[] chain) { chain = Optimize(chain).ToArray(); var dbg = DebugInfoGenerator.CreatePdbGenerator(); var outputElementType = chain.Last().OutputType; var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.RunAndSave); var mod = asm.DefineDynamicModule("Artifacts.dll", true); var stt = mod.DefineType("<>__Fused01_State", TypeAttributes.Class, typeof(Sink <>).MakeGenericType(outputElementType)); /* TODO: hoist non-trivial constants to params object passed to ctor * var foo = stt.DefineMethod("Foo", MethodAttributes.Public | MethodAttributes.Static, typeof(int), Type.EmptyTypes); * var p = new { Age = 21 }; * Expression<Func<int>> f = Expression.Lambda<Func<int>>(Expression.Property(Expression.Constant(p), "Age")); * f.CompileToMethod(foo); */ var sttCtor = stt.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] { typeof(IObserver <>).MakeGenericType(outputElementType), typeof(IDisposable) }); var sttCtorIlg = sttCtor.GetILGenerator(); sttCtorIlg.Emit(OpCodes.Ldarg_0); sttCtorIlg.Emit(OpCodes.Ldarg_1); sttCtorIlg.Emit(OpCodes.Ldarg_2); sttCtorIlg.Emit(OpCodes.Call, typeof(Sink <>).MakeGenericType(outputElementType).GetConstructors()[0]); sttCtorIlg.Emit(OpCodes.Ret); var dirty = stt.DefineField("dirty", typeof(bool), FieldAttributes.Public); var fldIndex = 0; FieldBuilder declareField(Type t) => stt.DefineField("state" + fldIndex++, t, FieldAttributes.Public); #if HOIST var mtdOnNextIndex = 0; MethodBuilder declareOnNext(Type t) => stt.DefineMethod("OnNext" + mtdOnNextIndex++, MethodAttributes.Public, typeof(void), new[] { t }); var mtdOnErrorIndex = 0; MethodBuilder declareOnError() => stt.DefineMethod("OnError" + mtdOnErrorIndex++, MethodAttributes.Public, typeof(void), new[] { typeof(Exception) }); var mtdOnCompletedIndex = 0; MethodBuilder declareOnCompleted() => stt.DefineMethod("OnCompleted" + mtdOnCompletedIndex++, MethodAttributes.Public, typeof(void), Type.EmptyTypes); #endif var methods = new Dictionary <MethodBuilder, LambdaExpression>(); var ctorBlock = new List <Expression>(); Action <Expression> appendToCtor = ctorBlock.Add; var stateParameter = Expression.Parameter(stt); var markDirty = Expression.Assign(Expression.Field(stateParameter, dirty), Expression.Constant(true)); var result = Expression.Parameter(typeof(IObserver <>).MakeGenericType(outputElementType)); var disposable = Expression.Parameter(typeof(IDisposable)); var curOnNext = default(Func <Expression, Expression>); var curOnError = default(Func <Expression, Expression>); var curOnCompleted = default(Expression); foreach (var op in chain.Reverse()) { op.Initialize(stateParameter, declareField, appendToCtor, result, disposable); var oldOnNext = curOnNext; var oldOnError = curOnError; var oldOnCompleted = curOnCompleted; #if HOIST if ((op.Hoist & HoistOperations.OnNext) != 0) { var onNext = declareOnNext(op.OutputType); var onNextValue = Expression.Parameter(op.OutputType); var onNextMtd = Expression.Lambda(oldOnNext(onNextValue), onNextValue); methods[onNext] = onNextMtd; // TODO: replace oldOnNext } if ((op.Hoist & HoistOperations.OnError) != 0) { var onError = declareOnError(); var onErrorValue = Expression.Parameter(typeof(Exception)); var onErrorMtd = Expression.Lambda(oldOnError(onErrorValue), onErrorValue); methods[onError] = onErrorMtd; // TODO: replace oldOnError } if ((op.Hoist & HoistOperations.OnCompleted) != 0) { var onCompleted = declareOnCompleted(); var onCompletedMtd = Expression.Lambda(oldOnCompleted); methods[onCompleted] = onCompletedMtd; // TODO: replace oldOnCompleted } #endif curOnNext = op.CreateOnNext(oldOnNext, oldOnError, oldOnCompleted, stateParameter, markDirty); curOnError = op.CreateOnError(oldOnNext, oldOnError, oldOnCompleted, stateParameter, markDirty); curOnCompleted = op.CreateOnCompleted(oldOnNext, oldOnError, oldOnCompleted, stateParameter, markDirty); } var ivOnNextValue = Expression.Parameter(inputElementType); var ivOnNextBody = curOnNext(ivOnNextValue); var ivOnErrorValue = Expression.Parameter(typeof(Exception)); var ivOnErrorBody = curOnError(ivOnErrorValue); var ivOnCompletedBody = curOnCompleted; var ivCtorBody = (Expression)Expression.Empty(); if (ctorBlock.Count > 0) { ivCtorBody = Expression.Block(ctorBlock.Concat(new[] { ivCtorBody })); } var stateType = stt.CreateType(); var stateParameterNew = Expression.Parameter(stateType); var subst = new CloseStateParameter(stateParameter, stateParameterNew); ivOnNextBody = subst.Visit(ivOnNextBody); ivOnErrorBody = subst.Visit(ivOnErrorBody); ivOnCompletedBody = subst.Visit(ivOnCompletedBody); ivCtorBody = subst.Visit(ivCtorBody); var ivOnNext = Expression.Lambda(ivOnNextBody, stateParameterNew, ivOnNextValue); var ivOnError = Expression.Lambda(ivOnErrorBody, stateParameterNew, ivOnErrorValue); var ivOnCompleted = Expression.Lambda(ivOnCompletedBody, stateParameterNew); var ivCtor = Expression.Lambda(ivCtorBody, stateParameterNew, result, disposable); var typ = mod.DefineType("<>__Fused01", TypeAttributes.Public, stateType, new[] { typeof(IObserver <>).MakeGenericType(inputElementType) }); var ivOnNextMtdImpl = typ.DefineMethod("OnNextImpl", MethodAttributes.Private | MethodAttributes.Static, typeof(void), new[] { stateType, inputElementType }); ivOnNextMtdImpl.SetImplementationFlags(MethodImplAttributes.AggressiveInlining); ivOnNext.CompileToMethod(ivOnNextMtdImpl, dbg); var ivOnNextMtd = typ.DefineMethod("OnNext", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), new[] { inputElementType }); var ivOnNextIlg = ivOnNextMtd.GetILGenerator(); ivOnNextIlg.Emit(OpCodes.Ldarg_0); ivOnNextIlg.Emit(OpCodes.Ldarg_1); ivOnNextIlg.EmitCall(OpCodes.Call, ivOnNextMtdImpl, null); ivOnNextIlg.Emit(OpCodes.Ret); var ivOnErrorMtdImpl = typ.DefineMethod("OnErrorImpl", MethodAttributes.Private | MethodAttributes.Static, typeof(void), new[] { stateType, typeof(Exception) }); ivOnErrorMtdImpl.SetImplementationFlags(MethodImplAttributes.AggressiveInlining); ivOnError.CompileToMethod(ivOnErrorMtdImpl, dbg); var ivOnErrorMtd = typ.DefineMethod("OnError", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), new[] { typeof(Exception) }); var ivOnErrorIlg = ivOnErrorMtd.GetILGenerator(); ivOnErrorIlg.Emit(OpCodes.Ldarg_0); ivOnErrorIlg.Emit(OpCodes.Ldarg_1); ivOnErrorIlg.EmitCall(OpCodes.Call, ivOnErrorMtdImpl, null); ivOnErrorIlg.Emit(OpCodes.Ret); var ivOnCompletedMtdImpl = typ.DefineMethod("OnCompletedImpl", MethodAttributes.Private | MethodAttributes.Static, typeof(void), new[] { stateType }); ivOnCompleted.CompileToMethod(ivOnCompletedMtdImpl, dbg); var ivOnCompletedMtd = typ.DefineMethod("OnCompleted", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes); ivOnCompletedMtdImpl.SetImplementationFlags(MethodImplAttributes.AggressiveInlining); var ivOnCompletedIlg = ivOnCompletedMtd.GetILGenerator(); ivOnCompletedIlg.Emit(OpCodes.Ldarg_0); ivOnCompletedIlg.EmitCall(OpCodes.Call, ivOnCompletedMtdImpl, null); ivOnCompletedIlg.Emit(OpCodes.Ret); var ivCtorMtdImpl = typ.DefineMethod(".ctorImpl", MethodAttributes.Private | MethodAttributes.Static, typeof(void), new[] { stateType, result.Type, typeof(IDisposable) }); ivCtor.CompileToMethod(ivCtorMtdImpl, dbg); var ivCtorMtd = typ.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] { result.Type, typeof(IDisposable) }); ivCtorMtdImpl.SetImplementationFlags(MethodImplAttributes.AggressiveInlining); var ivCtorIlg = ivCtorMtd.GetILGenerator(); ivCtorIlg.Emit(OpCodes.Ldarg_0); ivCtorIlg.Emit(OpCodes.Ldarg_1); ivCtorIlg.Emit(OpCodes.Ldarg_2); ivCtorIlg.Emit(OpCodes.Call, stateType.GetConstructors()[0]); ivCtorIlg.Emit(OpCodes.Ldarg_0); ivCtorIlg.Emit(OpCodes.Ldarg_1); ivCtorIlg.Emit(OpCodes.Ldarg_2); ivCtorIlg.EmitCall(OpCodes.Call, ivCtorMtdImpl, null); ivCtorIlg.Emit(OpCodes.Ret); var ivt = typ.CreateType(); asm.Save("Artifacts.dll"); return(ivt); }
public void CompileToMethod(MethodBuilder method, DebugInfoGenerator debugInfoGenerator) { CompileToMethod(method); }
/// <summary> /// Produces a delegate that represents the lambda expression. /// </summary> /// <param name="debugInfoGenerator">Debugging information generator used by the compiler to mark sequence points and annotate local variables.</param> /// <returns>A delegate containing the compiled version of the lambda.</returns> public Delegate Compile(DebugInfoGenerator debugInfoGenerator) { return(Compile()); }
public DebugInfoSymbolWriter(DebugInfoGenerator debugInfoGenerator) { this.debugInfoGenerator = debugInfoGenerator; }
/// <summary> /// Produces a delegate that represents the lambda expression. /// </summary> /// <param name="debugInfoGenerator">Debugging information generator used by the compiler to mark sequence points and annotate local variables.</param> /// <returns>A delegate containing the compiled version of the lambda.</returns> public new TDelegate Compile(DebugInfoGenerator debugInfoGenerator) { ContractUtils.RequiresNotNull(debugInfoGenerator, "debugInfoGenerator"); return((TDelegate)(object)LambdaCompiler.Compile(this, debugInfoGenerator)); }
/// <summary></summary> public void CompileToMethod(MethodBuilder method, DebugInfoGenerator debugInfoGenerator) { Predicate.CompileToMethod(method, debugInfoGenerator); }
public static TDelegate Compile <TDelegate>(Expression <TDelegate> lambda, CompilerOptions options) where TDelegate : class { CheckLambdaParameters(lambda); CompiledLambda[] subLambdas; var debugInfoGenerator = string.IsNullOrEmpty(DebugOutputDirectory) ? null : DebugInfoGenerator.CreatePdbGenerator(); return((TDelegate)(object)CompileInternal(lambda, debugInfoGenerator, out subLambdas, options)); }
public Delegate Compile(DebugInfoGenerator debugInfoGenerator) { throw new NotImplementedException(); }
public static void CompileToMethod(LambdaExpression lambda, MethodBuilder method, DebugInfoGenerator debugInfoGenerator, CompilerOptions options) { CheckLambdaParameters(lambda); CompileToMethodInternal(lambda, method, debugInfoGenerator, options); }
public void CompileToMethod(MethodBuilder method, DebugInfoGenerator debugInfoGenerator) { throw new NotImplementedException(); }
/// <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, IMethodBuilderForLambdaCompiler method, DebugInfoGenerator debugInfoGenerator) { // 1. Bind lambda AnalyzedTree tree = AnalyzeLambda(ref lambda); tree.DebugInfoGenerator = debugInfoGenerator; // 2. Create lambda compiler LambdaCompiler c = new LambdaCompiler(tree, lambda, method); // 3. Emit c.EmitLambdaBody(); }
/// <summary> /// Creates a lambda compiler that will compile into the provided MethodBuilder /// </summary> private LambdaCompiler(AnalyzedTree tree, LambdaExpression lambda, MethodBuilder method, DebugInfoGenerator debugInfoGenerator) { 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; _debugInfoGenerator = debugInfoGenerator; _ilg = method.GetILGenerator(); // These are populated by AnalyzeTree/VariableBinder _scope = scope; _boundConstants = tree.Constants[lambda]; InitializeMethod(); }