protected override Expression VisitGoto(GotoExpression node) { BranchLabel label; var target = node.Target; var value = Visit(node.Value); // TODO: Is it possible for an inner reducible node of the loop to rely on nodes produced by reducing outer reducible nodes? // Unknown label => must be within the loop: if (!_labelMapping.TryGetValue(target, out label)) { return(node.Update(target, value)); } // Known label within the loop: if (label.TargetIndex >= _loopStartInstructionIndex && label.TargetIndex < _loopEndInstructionIndex) { return(node.Update(target, value)); } return(Expression.Return(_returnLabel, (value != null) ? Expression.Call(_frameVar, InterpretedFrame.GotoMethod, Expression.Constant(label.LabelIndex), AstUtils.Box(value)) : Expression.Call(_frameVar, InterpretedFrame.VoidGotoMethod, Expression.Constant(label.LabelIndex)), node.Type )); }
protected override Expression VisitGoto(GotoExpression node) { if (node.Target.Name == "Break") { return(node.Update(BreakTarget, null)); } else if (node.Target.Name == "Continue") { return(node.Update(ContinueTarget, null)); } return(base.VisitGoto(node)); }
public void UpdateDifferentTargetIsDifferent() { Expression value = Expression.Constant(0); GotoExpression ret = Expression.Break(Expression.Label(typeof(int)), value); Assert.NotSame(ret, ret.Update(Expression.Label(typeof(int)), value)); }
public void UpdateDiferentValueIsDifferent() { LabelTarget target = Expression.Label(typeof(int)); GotoExpression ret = Expression.Break(target, Expression.Constant(0)); Assert.NotSame(ret, ret.Update(target, Expression.Constant(0))); }
protected override Expression VisitGoto(GotoExpression node) { BranchLabel label; LabelTarget key = node.Target; Expression expression = this.Visit(node.Value); if (!this._labelMapping.TryGetValue(key, out label)) { return(node.Update(key, expression)); } if ((label.TargetIndex >= this._loopStartInstructionIndex) && (label.TargetIndex < this._loopEndInstructionIndex)) { return(node.Update(key, expression)); } return(Expression.Return(this._returnLabel, ((expression != null) && (expression.Type != typeof(void))) ? Expression.Call(this._frameVar, InterpretedFrame.GotoMethod, Expression.Constant(label.LabelIndex), Utils.Box(expression)) : Expression.Call(this._frameVar, InterpretedFrame.VoidGotoMethod, new Expression[] { Expression.Constant(label.LabelIndex) }), node.Type)); }
public void UpdateSameIsSame() { LabelTarget target = Expression.Label(typeof(int)); Expression value = Expression.Constant(0); GotoExpression ret = Expression.Goto(target, value); Assert.Same(ret, ret.Update(target, value)); }
public void UpdateSameIsSame() { LabelTarget target = Expression.Label(typeof(int)); Expression value = Expression.Constant(0); GotoExpression ret = Expression.Break(target, value); Assert.Same(ret, ret.Update(target, value)); Assert.Same(ret, NoOpVisitor.Instance.Visit(ret)); }
protected override Expression VisitGoto(GotoExpression node) { var constant = node.Value as ConstantExpression; Expression value = _defaultValue; if (constant != null && (bool)constant.Value) { value = _ifTure; } return(node.Update(this.VisitLabelTarget(node.Target), value)); }
public T?Simplify <T>(T?expression) where T : Expression { if (expression is null) { return(null); } Expression expr = expression.Reduce() switch { UnaryExpression unaryExpr => unaryExpr.Update(Simplify(unaryExpr.Operand)), BinaryExpression binaryExpr => binaryExpr.Update(Simplify(binaryExpr.Left), binaryExpr.Conversion, Simplify(binaryExpr.Right)), LambdaExpression lambdaExpr => Expression.Lambda(Simplify(lambdaExpr.Body), lambdaExpr.Name, lambdaExpr.TailCall, Simplify(lambdaExpr.Parameters)), TryExpression tryExpr => tryExpr.Update(Simplify(tryExpr.Body), Simplify(tryExpr.Handlers), Simplify(tryExpr.Finally), Simplify(tryExpr.Fault)), NewExpression newExpr => newExpr.Update(Simplify(newExpr.Arguments)), GotoExpression gotoExpr => gotoExpr.Update(gotoExpr.Target, Simplify(gotoExpr.Value)), LoopExpression loopExpr => loopExpr.Update(loopExpr.BreakLabel, loopExpr.ContinueLabel, Simplify(loopExpr.Body)), BlockExpression blockExpr => blockExpr.Update(Simplify(blockExpr.Variables), Simplify(blockExpr.Expressions)), IndexExpression indexExpr => indexExpr.Update(Simplify(indexExpr.Object) !, Simplify(indexExpr.Arguments)), LabelExpression labelExpr => labelExpr.Update(labelExpr.Target, Simplify(labelExpr.DefaultValue)), MemberExpression memberExpr => memberExpr.Update(Simplify(memberExpr.Expression)), SwitchExpression switchExpr => switchExpr.Update(Simplify(switchExpr.SwitchValue), Simplify(switchExpr.Cases), Simplify(switchExpr.DefaultBody)), DynamicExpression dynamicExpr => dynamicExpr.Update(Simplify(dynamicExpr.Arguments)), ListInitExpression listInitExpr => listInitExpr.Update(Simplify(listInitExpr.NewExpression), Simplify(listInitExpr.Initializers)), NewArrayExpression newArrayExpr => newArrayExpr.Update(Simplify(newArrayExpr.Expressions)), InvocationExpression invokeExpr => invokeExpr.Update(Simplify(invokeExpr.Expression), Simplify(invokeExpr.Arguments)), MemberInitExpression memberInitExpr => memberInitExpr.Update(Simplify(memberInitExpr.NewExpression), memberInitExpr.Bindings), MethodCallExpression methodCallExpr => methodCallExpr.Update(Simplify(methodCallExpr.Object), Simplify(methodCallExpr.Arguments)), TypeBinaryExpression typeBinaryExpr => typeBinaryExpr.Update(Simplify(typeBinaryExpr.Expression)), ConditionalExpression condExpr => condExpr.Update(Simplify(condExpr.Test), Simplify(condExpr.IfTrue), Simplify(condExpr.IfFalse)), RuntimeVariablesExpression runtimeVarExpr => runtimeVarExpr.Update(Simplify(runtimeVarExpr.Variables)), _ => expression }; foreach (var transform in transformers) { expr = transform.Transform(expr, this); } return((T)expr); }
/// <summary> /// Visits the children of the <see cref="GotoExpression" />. /// </summary> /// <param name="node">The expression to visit.</param> /// <returns>The modified expression, if it or any subexpression was modified; /// otherwise, returns the original expression.</returns> protected internal virtual Expression VisitGoto(GotoExpression node) { return(node.Update(VisitLabelTarget(node.Target), Visit(node.Value))); }
private static Expression SetChildren(ReadOnlySpan <Expression> newChildren, GotoExpression g) => g.Update(g.Target, g.Value == null ? null : newChildren[0]);
/// <summary> /// Visits the children of the <see cref="GotoExpression"/>. /// </summary> /// <param name="node">The expression to visit.</param> /// <returns>The modified expression, if it or any subexpression was modified; /// otherwise, returns the original expression.</returns> protected override Expression VisitGoto(GotoExpression node) { return(node.Update(VisitLabelTarget(node.Target), Visit(node.Value))); }
protected virtual Expression VisitGoto(GotoExpression node, Type expectedType) => node.Update(VisitLabelTarget(node.Target, expectedType), Visit(node.Value, node.Target.Type == typeof(void) ? null : node.Target.Type));