public static Expression Rewrite(Expression expression, out LabelTarget exitLabel, out ParameterExpression pendingBranch, out IDictionary<LabelTarget, LeaveLabelData> leaveLabels) { pendingBranch = Expression.Parameter(typeof(int), "__pendingBranch"); exitLabel = Expression.Label("__leave"); var labelScanner = new LabelScanner(); labelScanner.Visit(expression); var gotoScanner = new GotoScanner(labelScanner.Labels, exitLabel, pendingBranch); var res = gotoScanner.Visit(expression); leaveLabels = gotoScanner.LeaveLabels; return res; }
public static Expression Rewrite(Expression expression, out LabelTarget exitLabel, out ParameterExpression pendingBranch, out IDictionary <LabelTarget, LeaveLabelData> leaveLabels) { pendingBranch = Expression.Parameter(typeof(int), "__pendingBranch"); exitLabel = Expression.Label("__leave"); var labelScanner = new LabelScanner(); labelScanner.Visit(expression); var gotoScanner = new GotoScanner(labelScanner.Labels, exitLabel, pendingBranch); var res = gotoScanner.Visit(expression); leaveLabels = gotoScanner.LeaveLabels; return(res); }
private Expression RewriteHandler(Expression body) { // // 1. Get accessors to the resulting Value and Index. // var leaveResultValue = Expression.PropertyOrField(_leaveResult, "Value"); // // 2. Compute gotos that leave the body. // var gotoScanner = new GotoScanner(_labelScanner.Labels); gotoScanner.Visit(body); // // 3. Rewrite body. // var leaveLabel = Expression.Label(typeof(LeaveHandlerData)); var rewriter = new Rewriter(leaveLabel, gotoScanner.LeaveLabels); var newBody = rewriter.Rewrite(body); // // 4. Create dispatch table. // if (gotoScanner.LeaveLabels.Count > 0) { _jumpTable.AddRange(gotoScanner.LeaveLabels.Select(kv => { var index = Expression.Constant(kv.Value); var label = kv.Key; var value = label.Type == typeof(void) ? null : Expression.Convert(leaveResultValue, label.Type); var jump = Expression.Goto(label, value); return(Expression.SwitchCase(jump, index)); })); } return(newBody); }
private Expression RewriteHandler(Expression body) { // // 1. Get accessors to the resulting Value and Index. // var leaveResultValue = Expression.PropertyOrField(_leaveResult, "Value"); // // 2. Compute gotos that leave the body. // var gotoScanner = new GotoScanner(_labelScanner.Labels); gotoScanner.Visit(body); // // 3. Rewrite body. // var leaveLabel = Expression.Label(typeof(LeaveHandlerData)); var rewriter = new Rewriter(leaveLabel, gotoScanner.LeaveLabels); var newBody = rewriter.Rewrite(body); // // 4. Create dispatch table. // if (gotoScanner.LeaveLabels.Count > 0) { _jumpTable.AddRange(gotoScanner.LeaveLabels.Select(kv => { var index = Expression.Constant(kv.Value); var label = kv.Key; var value = label.Type == typeof(void) ? null : Expression.Convert(leaveResultValue, label.Type); var jump = Expression.Goto(label, value); return Expression.SwitchCase(jump, index); })); } return newBody; }