public Expression Build(IEventTraceOperand operand, ParameterExpression eventRecordReader, ParameterExpression eventRecordWriter, ParameterExpression eventMetadataTable, ParameterExpression runtimeMetadata) { var eventMetadata = Expression.Parameter(typeof(EventMetadata)); var properties = Expression.Parameter(typeof(PropertyMetadata[])); var variables = new List <ParameterExpression> { eventMetadata, properties }; var expGenerator = new ExpressionGenerator(eventRecordReader, eventRecordWriter, properties); var list = new List <Expression> { Expression.Assign(eventMetadata, Expression.ArrayAccess(eventMetadataTable, Expression.Constant(operand.EventMetadataTableIndex))), Expression.Assign(properties, Expression.PropertyOrField(eventMetadata, "Properties")), eventRecordWriter.Call("WriteEventBegin", eventMetadata, runtimeMetadata), expGenerator.CodeGenerate(operand.EventPropertyOperands), eventRecordWriter.Call("WriteEventEnd") }; var returnExpression = Expression.Block(variables, list); return(returnExpression); }
internal MethodCallExpression Reduce(ParameterExpression awaiterHolder, uint state, LabelTarget stateLabel, LabelTarget returnLabel, CodeInsertionPoint prologue) { prologue(Assign(awaiterHolder, GetAwaiter)); prologue(Condition(new MoveNextExpression(awaiterHolder, state), Empty(), Return(returnLabel), typeof(void))); prologue(stateLabel.LandingSite()); return(awaiterHolder.Call(GetResultMethod)); }
// for asynchronous collection internal ForEachExpression(Expression collection, Expression cancellationToken, bool configureAwait, LabelTarget?continueLabel, LabelTarget?breakLabel) { collection.Type.GetItemType(out var enumerable); if (enumerable is null || !enumerable.IsConstructedGenericType || enumerable.GetGenericTypeDefinition() != typeof(IAsyncEnumerable <>)) { throw new ArgumentException(ExceptionMessages.AsyncEnumerableExpected, nameof(collection)); } if (cancellationToken.Type != typeof(CancellationToken)) { throw new ArgumentException(ExceptionMessages.TypeExpected <CancellationToken>(), nameof(cancellationToken)); } this.configureAwait = configureAwait; // enumerator = enumerable.GetAsyncEnumerator(token); const string GetAsyncEnumeratorMethod = nameof(IAsyncEnumerable <Missing> .GetAsyncEnumerator); MethodCallExpression getEnumerator = collection.Call(GetAsyncEnumeratorMethod, cancellationToken); enumeratorVar = Variable(getEnumerator.Type, EnumeratorVarName); enumeratorAssignment = Assign(enumeratorVar, getEnumerator); // discover async MoveNext moveNextCall = enumeratorVar.Call(nameof(IAsyncEnumerator <Missing> .MoveNextAsync)); Element = Property(enumeratorVar, nameof(IAsyncEnumerator <Missing> .Current)); BreakLabel = breakLabel ?? Label(typeof(void), BreakLabelName); ContinueLabel = continueLabel ?? Label(typeof(void), ContinueLabelName); }
// for synchronous collection internal ForEachExpression(Expression collection, LabelTarget?continueLabel, LabelTarget?breakLabel) { collection.Type.GetItemType(out var enumerable); const string GetEnumeratorMethod = nameof(IEnumerable.GetEnumerator); MethodCallExpression getEnumerator; if (enumerable is null) { getEnumerator = collection.Call(collection.Type.GetMethod(GetEnumeratorMethod, Array.Empty <Type>()) ?? throw new ArgumentException(ExceptionMessages.EnumerablePatternExpected)); enumeratorVar = Variable(getEnumerator.Method.ReturnType, EnumeratorVarName); moveNextCall = Call(enumeratorVar, nameof(IEnumerator.MoveNext), Array.Empty <Type>()); } else { getEnumerator = collection.Call(enumerable, GetEnumeratorMethod); enumeratorVar = Variable(getEnumerator.Method.ReturnType, EnumeratorVarName); // enumerator.MoveNext() moveNextCall = enumeratorVar.Call(typeof(IEnumerator), nameof(IEnumerator.MoveNext)); } // enumerator = enumerable.GetEnumerator(); enumeratorAssignment = Assign(enumeratorVar, getEnumerator); Element = Property(enumeratorVar, nameof(IEnumerator.Current)); BreakLabel = breakLabel ?? Label(typeof(void), BreakLabelName); ContinueLabel = continueLabel ?? Label(typeof(void), ContinueLabelName); }
internal override Expression Reduce(ParameterExpression stateMachine) { const BindingFlags PublicInstance = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; var moveNext = stateMachine.Type.GetMethod(nameof(AsyncStateMachine <ValueTuple> .MoveNext), PublicInstance, 1, null, typeof(uint)).MakeGenericMethod(awaiter.Type); return(stateMachine.Call(moveNext, awaiter, base.StateId)); }
internal override Expression Reduce(ParameterExpression stateMachine) { const BindingFlags PublicInstanceFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; var genericParam = Type.MakeGenericMethodParameter(0).MakeByRefType(); var moveNext = stateMachine.Type.GetMethod(nameof(AsyncStateMachine <ValueTuple> .MoveNext), 1, PublicInstanceFlags, null, new[] { genericParam, typeof(uint) }, null) !.MakeGenericMethod(awaiter.Type); return(stateMachine.Call(moveNext, awaiter, base.StateId)); }
internal override Expression Reduce(ParameterExpression stateMachine) { var tryRecover = stateMachine.Type.GetMethod(nameof(AsyncStateMachine <ValueTuple> .TryRecover)); Debug.Assert(!(tryRecover is null)); tryRecover = tryRecover.MakeGenericMethod(Receiver.Type); return(stateMachine.Call(tryRecover, Receiver)); }
internal Expression Reduce(ParameterExpression stateMachine, LabelTarget endOfAsyncMethod) { // if state machine is non-void then use Result property var resultProperty = stateMachine.Type.GetProperty(nameof(AsyncStateMachine <ValueTuple, int> .Result)); return(resultProperty is null? Block(AsyncResult, stateMachine.Call(nameof(AsyncStateMachine <ValueTuple> .Complete)), endOfAsyncMethod.Return()) : Block(Property(stateMachine, resultProperty).Assign(AsyncResult), endOfAsyncMethod.Return())); }
private LambdaExpression MakeSwitchLambda(ParameterExpression property, ParameterExpression rawValue) { var c = ReflectionCacheManager.GetEnumCache(propertyType).Cache; var fields = c.Fields; List <SwitchCase> cases = new List <SwitchCase>(); foreach (var f in fields) { if (f.Field.FieldType.IsEnum) { var val = f.Field.GetValue(null); Expression body = GetCaseBody((Enum)val, rawValue); if (body != null) { if (body.NodeType != ExpressionType.Block) { body = Expression.Convert(body, typeof(object)); } cases.Add(Expression.SwitchCase(body, Expression.Constant(val))); } } } var @default = Expression.Constant(null); var assignName = XmlExpressionConstants.Serializer_Name(XmlAttributeType.Element).Assign(property.Call("ToString").Call("ToLower")); var @switch = Expression.Switch(property, @default, cases.ToArray()); return(Expression.Lambda( Expression.Block( assignName, @switch ), "ReadObjectPropertyInner", new[] { XmlExpressionConstants.Serializer, property, rawValue })); }
internal override Expression Reduce(ParameterExpression stateMachine) => stateMachine.Call(nameof(AsyncStateMachine <ValueTuple> .ExitGuardedCode), StateId);
internal override Expression Reduce(ParameterExpression stateMachine) => stateMachine.Call(nameof(AsyncStateMachine <ValueTuple> .Rethrow));