Beispiel #1
0
        public GotoStatement CreateGoto(InternalLabel target, int depth)
        {
            var result = CreateGoto(LexicalInfo.Empty, target);

            AstAnnotations.SetTryBlockDepth(result, depth);
            return(result);
        }
Beispiel #2
0
        public InternalLabel CreateLabel(Node sourceNode, string name, int depth)
        {
            var result = CreateLabel(sourceNode, name);

            AstAnnotations.SetTryBlockDepth(result.LabelStatement, depth);
            return(result);
        }
Beispiel #3
0
 public override void Run()
 {
     foreach (Module module in this.CompileUnit.Modules)
     {
         AstAnnotations.MarkRawArrayIndexing(module);
     }
 }
Beispiel #4
0
        private Block GenerateAwaitForIncompleteTask(InternalLocal awaiterTemp)
        {
            var stateNumber = _labels.Count;
            var resumeLabel = CreateLabel(awaiterTemp.Node);

            IType awaiterFieldType = awaiterTemp.Type.IsVerifierReference()
                ? TypeSystemServices.ObjectType
                : awaiterTemp.Type;

            Field awaiterField = GetAwaiterField(awaiterFieldType);

            var blockBuilder = new Block();

            // this.state = _cachedState = stateForLabel
            blockBuilder.Add(new ExpressionStatement(SetStateTo(stateNumber)));

            blockBuilder.Add(
                // this.<>t__awaiter = $awaiterTemp
                CodeBuilder.CreateFieldAssignment(
                    awaiterField,
                    awaiterField.Type == awaiterTemp.Type
                        ? CodeBuilder.CreateLocalReference(awaiterTemp)
                        : CodeBuilder.CreateCast(awaiterFieldType, CodeBuilder.CreateLocalReference(awaiterTemp))));

            blockBuilder.Add(GenerateAwaitOnCompleted(awaiterTemp.Type, awaiterTemp));

            blockBuilder.Add(GenerateReturn());

            blockBuilder.Add(resumeLabel);
            AstAnnotations.SetTryBlockDepth(resumeLabel, blockBuilder.GetAncestors <TryStatement>().Count());

            var awaiterFieldRef = CodeBuilder.CreateMemberReference(
                CodeBuilder.CreateSelfReference(_stateMachineClass.Entity),
                (IField)awaiterField.Entity);

            blockBuilder.Add(
                // $awaiterTemp = this.<>t__awaiter   or   $awaiterTemp = (AwaiterType)this.<>t__awaiter
                // $this.<>t__awaiter = null;
                CodeBuilder.CreateAssignment(
                    CodeBuilder.CreateLocalReference(awaiterTemp),
                    awaiterTemp.Type == awaiterField.Type
                        ? awaiterFieldRef
                        : CodeBuilder.CreateCast(awaiterTemp.Type, awaiterFieldRef)));

            blockBuilder.Add(
                CodeBuilder.CreateFieldAssignment(
                    awaiterField,
                    CodeBuilder.CreateDefaultInvocation(LexicalInfo.Empty, ((ITypedEntity)awaiterField.Entity).Type)));

            // this.state = _cachedState = NotStartedStateMachine
            blockBuilder.Add(new ExpressionStatement(SetStateTo(StateMachineStates.NotStartedStateMachine)));

            return(blockBuilder);
        }
Beispiel #5
0
        private void CheckTryJumps(MethodInvocationExpression dispatch)
        {
            var realLabels = _labels.Distinct().Select(l => int.Parse(l.Name.Substring(7))).ToList();
            var stateArg   = dispatch.Arguments[0];
            IEnumerable <IGrouping <TryStatement, InternalLabel> > labels;

            do
            {
                labels = dispatch.Arguments
                         .Skip(1)
                         .Select(arg => (InternalLabel)arg.Entity)
                         .Where(l => l.LabelStatement.GetAncestor <TryStatement>() != null)
                         .GroupBy(l => l.LabelStatement.GetAncestor <TryStatement>());
                foreach (var labelGroup in labels)
                {
                    var newLabel = CodeBuilder.CreateLabel(dispatch, UniqueName("TryLabel"));
                    var parent   = (Block)labelGroup.Key.ParentNode;
                    parent.Insert(parent.Statements.IndexOf(labelGroup.Key), newLabel.LabelStatement);
                    AstAnnotations.SetTryBlockDepth(newLabel.LabelStatement, parent.GetAncestors <TryStatement>().Count());
                    IfStatement innerDispatch = null;
                    foreach (var label in labelGroup)
                    {
                        var switchArg = dispatch.Arguments.First(arg => arg.Entity == label);
                        switchArg.Entity = newLabel;
                        var state = dispatch.Arguments.IndexOf(switchArg) - 1;
                        if (!realLabels.Contains(state))
                        {
                            continue;
                        }
                        var depth = label.LabelStatement.GetAncestors <TryStatement>().Count();
                        innerDispatch = new IfStatement(
                            CodeBuilder.CreateBoundBinaryExpression(
                                TypeSystemServices.BoolType,
                                BinaryOperatorType.Equality,
                                stateArg.CloneNode(),
                                new IntegerLiteralExpression(state)),
                            new Block(CodeBuilder.CreateGoto(label, depth)),
                            innerDispatch != null ? new Block(innerDispatch) : null);
                    }
                    if (innerDispatch != null)
                    {
                        labelGroup.Key.ProtectedBlock.Insert(0, innerDispatch);
                    }
                }
            } while (labels.Any());
        }
Beispiel #6
0
 public override Statement Expand(MacroStatement macro)
 {
     Debug.Assert(0 == macro.Arguments.Count);
     AstAnnotations.MarkChecked(macro.Block);
     return(macro.Block);
 }