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);
        }
示例#2
0
 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));
 }
示例#3
0
        // 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);
        }
示例#4
0
        // 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);
        }
示例#5
0
        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));
        }
示例#8
0
        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()));
        }
示例#9
0
        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);
示例#11
0
 internal override Expression Reduce(ParameterExpression stateMachine)
 => stateMachine.Call(nameof(AsyncStateMachine <ValueTuple> .Rethrow));