Exemple #1
0
        void Map()
        {
            IType         type   = (IType)_sharedLocalsClass.Entity;
            InternalLocal locals = CodeBuilder.DeclareLocal(_currentMethod, "___locals", type);

            foreach (ReferenceExpression reference in _references)
            {
                IField mapped = (IField)_mappings[reference.Entity];
                if (null != mapped)
                {
                    reference.ParentNode.Replace(
                        reference,
                        CodeBuilder.CreateMemberReference(
                            CodeBuilder.CreateReference(locals),
                            mapped));
                }
            }

            Block initializationBlock = new Block();

            initializationBlock.Add(CodeBuilder.CreateAssignment(
                                        CodeBuilder.CreateReference(locals),
                                        CodeBuilder.CreateConstructorInvocation(type.GetConstructors()[0])));
            InitializeSharedParameters(initializationBlock, locals);
            _currentMethod.Body.Statements.Insert(0, initializationBlock);

            foreach (IEntity entity in _mappings.Keys)
            {
                _currentMethod.Locals.RemoveByEntity(entity);
            }
        }
Exemple #2
0
            public InternalLabel ProxyReturnIfNeeded(
                Method containingMethod,
                Node valueOpt,
                out InternalLocal retVal)
            {
                retVal = null;

                // no need to proxy returns  at the root
                if (IsRoot())
                {
                    return(null);
                }

                var returnProxy = returnProxyLabel;

                if (returnProxy == null)
                {
                    returnProxyLabel = returnProxy = _builder.CreateLabel(valueOpt ?? containingMethod, "returnProxy", _tryDepth);
                }

                if (valueOpt != null)
                {
                    retVal = returnValue;
                    if (retVal == null)
                    {
                        Debug.Assert(_tryStatementOpt != null);
                        returnValue = retVal = _builder.DeclareTempLocal(
                            containingMethod,
                            ((ITypedEntity)valueOpt.Entity).Type);
                    }
                }

                return(returnProxy);
            }
Exemple #3
0
        private Block PendBranches(
            AwaitFinallyFrame frame,
            InternalLocal pendingBranchVar,
            InternalLabel finallyLabel)
        {
            var bodyStatements = new Block();

            // handle proxy labels if have any
            var proxiedLabels = frame.proxiedLabels;
            var proxyLabels   = frame.proxyLabels;

            // skip 0 - it means we took no explicit branches
            int i = 1;

            if (proxiedLabels != null)
            {
                for (int cnt = proxiedLabels.Count; i <= cnt; i++)
                {
                    var proxied = proxiedLabels[i - 1];
                    var proxy   = proxyLabels[proxied];

                    PendBranch(bodyStatements, proxy, i, pendingBranchVar, finallyLabel);
                }
            }

            var returnProxy = frame.returnProxyLabel;

            if (returnProxy != null)
            {
                PendBranch(bodyStatements, returnProxy, i, pendingBranchVar, finallyLabel);
            }

            return(bodyStatements);
        }
Exemple #4
0
        private void AddToMoveNextMethod(Local local)
        {
            var newLocal = new InternalLocal(local, _methodToStateMachineMapper.MapType(((InternalLocal)local.Entity).Type));

            _entityMapper.Add(local.Entity, newLocal);
            local.Entity = newLocal;
            _moveNext.Method.Locals.Add(local);
        }
Exemple #5
0
            public AwaitCatchFrame(TypeSystemServices tss, BooCodeBuilder builder, Method currentMethod)
            {
                pendingCaughtException = builder.DeclareTempLocal(currentMethod, tss.ObjectType);
                pendingCatch           = builder.DeclareTempLocal(currentMethod, tss.IntType);

                handlers              = new List <Block>();
                _hoistedLocals        = new Dictionary <InternalLocal, InternalLocal>();
                _orderedHoistedLocals = new List <InternalLocal>();
                _currentMethod        = currentMethod;
            }
Exemple #6
0
        private bool IsExceptionHandlerVariable(InternalLocal local)
        {
            Declaration originalDeclaration = local.OriginalDeclaration;

            if (originalDeclaration == null)
            {
                return(false);
            }
            return(originalDeclaration.ParentNode is ExceptionHandler);
        }
        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);
        }
 void CheckUnusedLocals(Method node)
 {
     foreach (Local local in node.Locals)
     {
         InternalLocal entity = (InternalLocal)local.Entity;
         if (!entity.IsPrivateScope && !entity.IsUsed)
         {
             Warnings.Add(CompilerWarningFactory.UnusedLocalVariable(local, local.Name));
         }
     }
 }
        public Block PrepareEvaluationContextInitialization(IType evaluationContextType)
        {
            this._evaluationContextLocal = this.CodeBuilder.DeclareTempLocal(this.CurrentMethodNode, evaluationContextType);
            Block block = new Block();

            block.Add(this.CodeBuilder.CreateAssignment(this.CreateEvaluationContextReference(), this.CodeBuilder.CreateConstructorInvocation(UtilitiesModule.ConstructorTakingNArgumentsFor(evaluationContextType, 1), this.EvaluationDomainProviderReference())));
            foreach (ParameterDeclaration declaration in this.CurrentMethodNode.Parameters)
            {
                block.Add(this.CodeBuilder.CreateAssignment(this.CreateEvaluationContextFieldReference(this.GetEvaluationContextField(declaration)), this.CodeBuilder.CreateReference(declaration)));
            }
            return(block);
        }
Exemple #10
0
            public void AddLocal(InternalLocal local)
            {
                if (_locals == null)
                {
                    _locals = new List <InternalLocal>();
                }

                if (local.Type.IsRestrictedType())
                {
                    CompilerContext.Current.Errors.Add(
                        CompilerErrorFactory.RestrictedAwaitType(local.Local, local.Type));
                }

                _locals.Add(local);
            }
        void ProcessAssignmentToSpecialMember(BinaryExpression node)
        {
            MemberReferenceExpression memberRef = (MemberReferenceExpression)node.Left;
            List chain = WalkMemberChain(memberRef);

            if (null == chain || 0 == chain.Count)
            {
                return;
            }

            MethodInvocationExpression eval = CodeBuilder.CreateEvalInvocation(node.LexicalInfo);

            // right hand side should always be executed before
            // left hand side
            InternalLocal value = DeclareTempLocal(GetExpressionType(node.Right));

            eval.Arguments.Add(
                CodeBuilder.CreateAssignment(
                    CodeBuilder.CreateReference(value),
                    node.Right));

            foreach (ChainItem item in chain)
            {
                item.Local = DeclareTempLocal(item.Container.ExpressionType);
                BinaryExpression tempInitialization = CodeBuilder.CreateAssignment(
                    node.LexicalInfo,
                    CodeBuilder.CreateReference(item.Local),
                    item.Container.CloneNode());
                item.Container.ParentNode.Replace(item.Container,
                                                  CodeBuilder.CreateReference(item.Local));
                eval.Arguments.Add(tempInitialization);
            }

            eval.Arguments.Add(
                CodeBuilder.CreateAssignment(node.LexicalInfo,
                                             node.Left,
                                             CodeBuilder.CreateReference(value)));

            PropagateChanges(eval, chain);

            if (NodeType.ExpressionStatement != node.ParentNode.NodeType)
            {
                eval.Arguments.Add(CodeBuilder.CreateReference(value));
                BindExpressionType(eval, value.Type);
            }

            ReplaceCurrentNode(eval);
        }
Exemple #12
0
 void InitializeSharedParameters(Block block, InternalLocal locals)
 {
     foreach (Node node in _currentMethod.Parameters)
     {
         InternalParameter param = (InternalParameter)node.Entity;
         if (param.IsShared)
         {
             block.Add(
                 CodeBuilder.CreateAssignment(
                     CodeBuilder.CreateMemberReference(
                         CodeBuilder.CreateReference(locals),
                         (IField)_mappings[param]),
                     CodeBuilder.CreateReference(param)));
         }
     }
 }
Exemple #13
0
        void CheckUnusedLocals(Method node)
        {
            foreach (Local local in node.Locals)
            {
                // _ is a commonly accepted dummy variable for unused items
                if (local.Name == "_")
                {
                    continue;
                }

                InternalLocal entity = (InternalLocal)local.Entity;
                if (!entity.IsPrivateScope && !entity.IsUsed)
                {
                    Warnings.Add(CompilerWarningFactory.UnusedLocalVariable(local, local.Name));
                }
            }
        }
        void CreateMoveNext()
        {
            Method generator = _generator.Method;

            BooMethodBuilder mn = _enumerator.AddVirtualMethod("MoveNext", TypeSystemServices.BoolType);

            mn.Method.LexicalInfo = this.LexicalInfo;
            _moveNext             = mn.Entity;

            foreach (Local local in generator.Locals)
            {
                InternalLocal entity = (InternalLocal)local.Entity;

                Field field = _enumerator.AddField("___" + entity.Name + _context.AllocIndex(), entity.Type);
                field.Modifiers |= TypeMemberModifiers.Internal;
                _mapping[entity] = field.Entity;
            }
            generator.Locals.Clear();

            foreach (ParameterDeclaration parameter in generator.Parameters)
            {
                InternalParameter entity = (InternalParameter)parameter.Entity;
                if (entity.IsUsed)
                {
                    Field field = DeclareFieldInitializedFromConstructorParameter(_enumerator, _enumeratorConstructor,
                                                                                  entity.Name,
                                                                                  entity.Type);
                    _mapping[entity] = field.Entity;
                }
            }

            mn.Body.Add(CreateLabel(generator));
            mn.Body.Add(generator.Body);
            generator.Body.Clear();

            Visit(mn.Body);

            mn.Body.Add(CreateYieldInvocation(null));
            mn.Body.Add(CreateLabel(generator));

            mn.Body.Insert(0,
                           CodeBuilder.CreateSwitch(
                               this.LexicalInfo,
                               CodeBuilder.CreateMemberReference(_state),
                               _labels));
        }
Exemple #15
0
        private void PendBranch(
            Block bodyStatements,
            InternalLabel proxy,
            int i,
            InternalLocal pendingBranchVar,
            InternalLabel finallyLabel)
        {
            // branch lands here
            bodyStatements.Add(proxy.LabelStatement);

            // pend the branch
            bodyStatements.Add(_F.CreateAssignment(
                                   _F.CreateLocalReference(pendingBranchVar),
                                   _F.CreateIntegerLiteral(i)));

            // skip other proxies
            bodyStatements.Add(_F.CreateGoto(finallyLabel, _tryDepth));
        }
Exemple #16
0
        public override void OnDeclaration(Declaration node)
        {
            if (node.Entity == null)
            {
                return;
            }
            var           catchFrame   = _currentAwaitCatchFrame;
            InternalLocal hoistedLocal = null;

            if (catchFrame == null || !catchFrame.TryGetHoistedLocal((InternalLocal)node.Entity, out hoistedLocal))
            {
                base.OnDeclaration(node);
            }

            ReplaceCurrentNode(new Declaration(node.Name, _F.CreateTypeReference(hoistedLocal.Type))
            {
                Entity = hoistedLocal
            });
        }
        public static void UnpackEnumerable(BooCodeBuilder codeBuilder, Method method, Block block, Expression expression, DeclarationCollection declarations)
        {
            TypeSystemServices tss = codeBuilder.TypeSystemServices;

            InternalLocal local = codeBuilder.DeclareTempLocal(method,
                                                               tss.IEnumeratorType);

            IType expressionType = expression.ExpressionType;

            if (expressionType.IsSubclassOf(codeBuilder.TypeSystemServices.IEnumeratorType))
            {
                block.Add(
                    codeBuilder.CreateAssignment(
                        codeBuilder.CreateReference(local),
                        expression));
            }
            else
            {
                if (!expressionType.IsSubclassOf(codeBuilder.TypeSystemServices.IEnumerableType))
                {
                    expression = codeBuilder.CreateMethodInvocation(
                        RuntimeServices_GetEnumerable, expression);
                }

                block.Add(
                    codeBuilder.CreateAssignment(
                        block.LexicalInfo,
                        codeBuilder.CreateReference(local),
                        codeBuilder.CreateMethodInvocation(
                            expression, IEnumerable_GetEnumerator)));
            }

            for (int i = 0; i < declarations.Count; ++i)
            {
                Declaration declaration = declarations[i];

                block.Add(
                    codeBuilder.CreateAssignment(
                        codeBuilder.CreateReference(declaration.Entity),
                        codeBuilder.CreateMethodInvocation(RuntimeServices_MoveNext,
                                                           codeBuilder.CreateReference(local))));
            }
        }
Exemple #18
0
            public void HoistLocal(InternalLocal local, BooCodeBuilder F)
            {
                if (!_hoistedLocals.Keys.Any(l => l.Name == local.Name && l.Type == local.Type))
                {
                    _hoistedLocals.Add(local, local);
                    _orderedHoistedLocals.Add(local);
                    return;
                }

                // code uses "await" in two sibling catches with exception filters
                // locals with same names and types may cause problems if they are lifted
                // and become fields with identical signatures.
                // To avoid such problems we will mangle the name of the second local.
                // This will only affect debugging of this extremely rare case.
                var newLocal = F.DeclareTempLocal(_currentMethod, local.Type);

                _hoistedLocals.Add(local, newLocal);
                _orderedHoistedLocals.Add(newLocal);
            }
        public override void OnBlock(Block node)
        {
            try
            {
                if (node.Statements.Count == 0 || node.Statements[0].NodeType != NodeType.Block)
                {
                    return;
                }

                var innerBlock = (Block)node.Statements[0];
                ExpressionStatement firstStatement;
                if (!IsSwitchStatementWithOnlyDefault(innerBlock, out firstStatement))
                {
                    return;
                }

                var binaryExp = (BinaryExpression)firstStatement.Expression;
                if (binaryExp.Operator != BinaryOperatorType.Assign || binaryExp.Left.NodeType != NodeType.ReferenceExpression || !binaryExp.Left.ToCodeString().Contains("$switch$"))
                {
                    return;
                }

                var originalLocal = ((InternalLocal)binaryExp.Left.Entity).Local;
                var varName       = originalLocal.Name.Replace("$", "_");
                var local         = new Local(varName, true);
                var internalLocal = new InternalLocal(local, binaryExp.ExpressionType);
                local.Entity = internalLocal;

                internalLocal.OriginalDeclaration = new Declaration(varName, CodeBuilder.CreateTypeReference(internalLocal.Type));

                // we need a DeclarationStatment as the parent of the "OriginalDeclaration"
                var ds = new DeclarationStatement(internalLocal.OriginalDeclaration, binaryExp.Right);

                innerBlock.Statements.RemoveAt(0);

                var parentMethod = node.GetAncestor <Method>();
                parentMethod.Locals.Replace(originalLocal, internalLocal.Local);
            }
            finally
            {
                base.OnBlock(node);
            }
        }
        public void AddLocalVariablesAsFields(BooClassBuilder builder)
        {
            Field field;

            foreach (Local local in this.CurrentMethodNode.Locals)
            {
                InternalLocal entity = (InternalLocal)this.GetEntity(local);
                if (!entity.IsPrivateScope)
                {
                    field = builder.AddPublicField(entity.Name, entity.Type);
                    this.SetEvaluationContextField(local, (InternalField)this.GetEntity(field));
                }
            }
            foreach (ParameterDeclaration declaration in this.CurrentMethodNode.Parameters)
            {
                InternalParameter parameter = (InternalParameter)this.GetEntity(declaration);
                field = builder.AddPublicField(parameter.Name, parameter.Type);
                this.SetEvaluationContextField(declaration, (InternalField)this.GetEntity(field));
            }
        }
        public override void OnReturnStatement(ReturnStatement node)
        {
            Statement result = CodeBuilder.CreateGoto(_exprReturnLabel, _tryStatementStack.Count + 1);

            if (node.Expression != null)
            {
                Debug.Assert(_isGenericTask || node.Expression.ExpressionType == TypeSystemServices.TaskType);
                if (_exprRetValue == null)
                {
                    _exprRetValue = CodeBuilder.DeclareTempLocal(_moveNext.Method, TypeSystemServices.TaskType);
                }

                result = new Block(
                    new ExpressionStatement(
                        CodeBuilder.CreateAssignment(
                            CodeBuilder.CreateLocalReference(_exprRetValue),
                            Visit(node.Expression))),
                    result);
            }
            ReplaceCurrentNode(result);
        }
            public override void OnWhileStatement(WhileStatement node)
            {
                if (node.OrBlock == null)
                {
                    return;
                }

                InternalLocal enteredLoop = CodeBuilder().DeclareTempLocal(_currentMethod, BoolType());

                IfStatement orPart = new IfStatement(
                    node.OrBlock.LexicalInfo,
                    CodeBuilder().CreateNotExpression(CodeBuilder().CreateReference(enteredLoop)),
                    node.OrBlock,
                    null);

                node.OrBlock = orPart.ToBlock();
                node.Block.Insert(0,
                                  CodeBuilder().CreateAssignment(
                                      CreateReference(enteredLoop),
                                      CreateTrueLiteral()));
            }
        public void TransformIteration(ForStatement node)
        {
            string[]      components = new string[] { "iterator" };
            InternalLocal local      = this.CodeBuilder.DeclareLocal(this.CurrentMethod, base._context.GetUniqueName(components), this.TypeSystemServices.IEnumeratorType);

            local.IsUsed = true;
            Block newNode = new Block(node.LexicalInfo);

            newNode.Add(this.CodeBuilder.CreateAssignment(node.LexicalInfo, this.CodeBuilder.CreateReference(local), node.Iterator));
            WhileStatement stmt = new WhileStatement(node.LexicalInfo)
            {
                Condition = this.CodeBuilder.CreateMethodInvocation(this.CodeBuilder.CreateReference(local), this.IEnumerator_MoveNext)
            };
            MethodInvocationExpression rhs = this.CodeBuilder.CreateMethodInvocation(this.CodeBuilder.CreateReference(local), this.IEnumerator_get_Current);
            InternalLocal entity           = (InternalLocal)TypeSystemServices.GetEntity(node.Declarations[0]);

            stmt.Block.Add(this.CodeBuilder.CreateAssignment(node.LexicalInfo, this.CodeBuilder.CreateReference(entity), rhs));
            stmt.Block.Add(node.Block);
            new LoopVariableUpdater(this, base._context, local, entity).Visit(node);
            newNode.Add(stmt);
            node.ParentNode.Replace(node, newNode);
        }
        private Statement GenerateAwaitOnCompleted(IType loweredAwaiterType, InternalLocal awaiterTemp)
        {
            // this.builder.AwaitOnCompleted<TAwaiter,TSM>(ref $awaiterTemp, ref this)
            //    or
            // this.builder.AwaitOnCompleted<TAwaiter,TSM>(ref $awaiterArrayTemp[0], ref this)
            var localEntity = MapNestedType(_stateMachineClass.Entity);

            InternalLocal selfTemp = _stateMachineClass.Entity.IsValueType ? null : CodeBuilder.DeclareTempLocal(_moveNext.Method, _stateMachineClass.Entity);

            var useUnsafeOnCompleted = loweredAwaiterType.IsAssignableFrom(ICriticalNotifyCompletionType);

            var onCompleted = (useUnsafeOnCompleted ?
                               _asyncMethodBuilderMemberCollection.AwaitUnsafeOnCompleted :
                               _asyncMethodBuilderMemberCollection.AwaitOnCompleted)
                              .GenericInfo.ConstructMethod(loweredAwaiterType, localEntity);

            var result =
                CodeBuilder.CreateMethodInvocation(
                    CodeBuilder.CreateMemberReference(
                        CodeBuilder.CreateSelfReference(localEntity),
                        (IField)_asyncMethodBuilderField.Entity),
                    onCompleted,
                    CodeBuilder.CreateLocalReference(awaiterTemp),
                    selfTemp != null ?
                    CodeBuilder.CreateLocalReference(selfTemp) :
                    (Expression)CodeBuilder.CreateSelfReference(localEntity));

            if (selfTemp != null)
            {
                result = CodeBuilder.CreateEvalInvocation(
                    LexicalInfo.Empty,
                    CodeBuilder.CreateAssignment(
                        CodeBuilder.CreateLocalReference(selfTemp),
                        CodeBuilder.CreateSelfReference(localEntity)),
                    result);
            }

            return(new ExpressionStatement(result));
        }
Exemple #25
0
        private Statement UnpendException(InternalLocal pendingExceptionLocal)
        {
            // create a temp.
            // pendingExceptionLocal will certainly be captured, no need to access it over and over.
            InternalLocal obj     = _F.DeclareTempLocal(_containingMethod, _tss.ObjectType);
            var           objInit = _F.CreateAssignment(_F.CreateLocalReference(obj), _F.CreateLocalReference(pendingExceptionLocal));

            // throw pendingExceptionLocal;
            Statement rethrow = Rethrow(obj);

            return(new Block(
                       new ExpressionStatement(objInit),
                       new IfStatement(
                           pendingExceptionLocal.Local.LexicalInfo,
                           _F.CreateBoundBinaryExpression(
                               _tss.BoolType,
                               BinaryOperatorType.ReferenceInequality,
                               _F.CreateLocalReference(obj),
                               new NullLiteralExpression()),
                           new Block(rethrow),
                           null)));
        }
Exemple #26
0
        private Statement Rethrow(InternalLocal obj)
        {
            // conservative rethrow
            Statement rethrow = new RaiseStatement(_F.CreateLocalReference(obj));

            // if these helpers are available, we can rethrow with original stack info
            // as long as it derives from Exception
            if (_exceptionDispatchInfoCapture != null && _exceptionDispatchInfoThrow != null)
            {
                var ex         = _F.DeclareTempLocal(_containingMethod, _tss.ExceptionType);
                var assignment = _F.CreateAssignment(
                    _F.CreateLocalReference(ex),
                    _F.CreateAsCast(ex.Type, _F.CreateLocalReference(obj)));

                // better rethrow
                rethrow = new Block(
                    new ExpressionStatement(assignment),
                    new IfStatement(
                        _F.CreateBoundBinaryExpression(
                            _tss.BoolType,
                            BinaryOperatorType.ReferenceEquality,
                            _F.CreateLocalReference(ex),
                            new NullLiteralExpression()),
                        new Block(rethrow),
                        null),
                    // ExceptionDispatchInfo.Capture(pendingExceptionLocal).Throw()
                    new ExpressionStatement(
                        _F.CreateMethodInvocation(
                            _F.CreateMethodInvocation(
                                _exceptionDispatchInfoCapture,
                                _F.CreateLocalReference(ex)),
                            _exceptionDispatchInfoThrow))
                    );
            }

            return(rethrow);
        }
Exemple #27
0
        private Expression CreateSideEffectAwareSlicingOperation(LexicalInfo lexicalInfo, BinaryOperatorType binaryOperator, SlicingExpression lvalue, Expression rvalue, InternalLocal returnValue)
        {
            MethodInvocationExpression eval = CodeBuilder.CreateEvalInvocation(lexicalInfo);
            if (HasSideEffect(lvalue.Target))
            {
                InternalLocal temp = AddInitializedTempLocal(eval, lvalue.Target);
                lvalue.Target = CodeBuilder.CreateReference(temp);
            }

            foreach (Slice slice in lvalue.Indices)
            {
                Expression index = slice.Begin;
                if (HasSideEffect(index))
                {
                    InternalLocal temp = AddInitializedTempLocal(eval, index);
                    slice.Begin = CodeBuilder.CreateReference(temp);
                }
            }

            BinaryExpression addition = CodeBuilder.CreateBoundBinaryExpression(
                GetExpressionType(lvalue),
                binaryOperator,
                CloneOrAssignToTemp(returnValue, lvalue),
                rvalue);
            Expression expansion = CodeBuilder.CreateAssignment(
                lvalue.CloneNode(),
                addition);
            // Resolve operator overloads if any
            BindArithmeticOperator(addition);
            if (eval.Arguments.Count > 0 || null != returnValue)
            {
                eval.Arguments.Add(expansion);
                if (null != returnValue)
                {
                    eval.Arguments.Add(CodeBuilder.CreateReference(returnValue));
                }
                BindExpressionType(eval, GetExpressionType(lvalue));
                expansion = eval;
            }
            return expansion;
        }
        override public void LeaveForStatement(ForStatement node)
        {
            _iteratorNode         = node.Iterator;
            CurrentEnumeratorType = GetExpressionType(node.Iterator);

            if (null == CurrentBestEnumeratorType)
            {
                return;                 //error
            }
            DeclarationCollection declarations = node.Declarations;
            Block body = new Block(node.LexicalInfo);

            InternalLocal iterator = CodeBuilder.DeclareLocal(_current,
                                                              Context.GetUniqueName("iterator"),
                                                              CurrentBestEnumeratorType);

            if (CurrentBestEnumeratorType == CurrentEnumeratorType)
            {
                //$iterator = <node.Iterator>
                body.Add(
                    CodeBuilder.CreateAssignment(
                        node.LexicalInfo,
                        CodeBuilder.CreateReference(iterator),
                        node.Iterator));
            }
            else
            {
                //$iterator = <node.Iterator>.GetEnumerator()
                body.Add(
                    CodeBuilder.CreateAssignment(
                        node.LexicalInfo,
                        CodeBuilder.CreateReference(iterator),
                        CodeBuilder.CreateMethodInvocation(node.Iterator, CurrentBestGetEnumerator)));
            }

            // while __iterator.MoveNext():
            if (null == CurrentBestMoveNext)
            {
                return;                 //error
            }
            WhileStatement ws = new WhileStatement(node.LexicalInfo);

            ws.Condition = CodeBuilder.CreateMethodInvocation(
                CodeBuilder.CreateReference(iterator),
                CurrentBestMoveNext);

            if (null == CurrentBestGetCurrent)
            {
                return;                 //error
            }
            Expression current = CodeBuilder.CreateMethodInvocation(
                CodeBuilder.CreateReference(iterator),
                CurrentBestGetCurrent);

            if (1 == declarations.Count)
            {
                //	item = __iterator.Current
                ws.Block.Add(
                    CodeBuilder.CreateAssignment(
                        node.LexicalInfo,
                        CodeBuilder.CreateReference((InternalLocal)declarations[0].Entity),
                        current));
            }
            else
            {
                UnpackExpression(ws.Block,
                                 CodeBuilder.CreateCast(
                                     CurrentEnumeratorItemType,
                                     current),
                                 node.Declarations);
            }

            ws.Block.Add(node.Block);
            ws.OrBlock   = node.OrBlock;
            ws.ThenBlock = node.ThenBlock;

            // try:
            //   while...
            // ensure:
            //   d = iterator as IDisposable
            //   d.Dispose() unless d is null
            if (IsAssignableFrom(TypeSystemServices.IDisposableType, CurrentBestEnumeratorType))
            {
                TryStatement tryStatement = new TryStatement();
                tryStatement.ProtectedBlock.Add(ws);
                tryStatement.EnsureBlock = new Block();

                CastExpression castExpression = new CastExpression();
                castExpression.Type           = CodeBuilder.CreateTypeReference(TypeSystemServices.IDisposableType);
                castExpression.Target         = CodeBuilder.CreateReference(iterator);
                castExpression.ExpressionType = TypeSystemServices.IDisposableType;
                tryStatement.EnsureBlock.Add(
                    CodeBuilder.CreateMethodInvocation(castExpression, IDisposable_Dispose));

                body.Add(tryStatement);
            }
            else
            {
                body.Add(ws);
            }

            ReplaceCurrentNode(body);
        }
 private ReferenceExpression CreateReference(InternalLocal enteredLoop)
 {
     return(CodeBuilder().CreateReference(enteredLoop));
 }
Exemple #30
0
        void SetLocal(BinaryExpression node, InternalLocal tag, bool leaveValueOnStack)
        {
            if (AstUtil.IsIndirection(node.Left))
                _il.Emit(OpCodes.Ldloc, tag.LocalBuilder);

            node.Right.Accept(this); // leaves type on stack

            IType typeOnStack = null;

            if (leaveValueOnStack)
            {
                typeOnStack = PeekTypeOnStack();
                _il.Emit(OpCodes.Dup);
            }
            else
            {
                typeOnStack = PopType();
            }

            if (!AstUtil.IsIndirection(node.Left))
                EmitAssignment(tag, typeOnStack);
            else
                EmitIndirectAssignment(tag, typeOnStack);
        }
Exemple #31
0
        void LoadLocal(InternalLocal local, bool byAddress)
        {
            _il.Emit(IsByAddress(local.Type) ? OpCodes.Ldloca : OpCodes.Ldloc, local.LocalBuilder);

            PushType(local.Type);
            _currentLocal = local.LocalBuilder;
        }
Exemple #32
0
 void LoadLocal(InternalLocal local)
 {
     LoadLocal(local, false);
 }
Exemple #33
0
 public ReferenceExpression CreateReference(InternalLocal local)
 {
     return CreateLocalReference(local.Name, local);
 }
Exemple #34
0
 public Expression CreateInitValueType(LexicalInfo li, InternalLocal local)
 {
     return CreateInitValueType(li, CreateReference(local));
 }
Exemple #35
0
        protected virtual IEntity DeclareLocal(Node sourceNode, string name, IType localType, bool privateScope)
        {
            ClearResolutionCacheFor(name);

            var local = new Local(name, privateScope);
            local.LexicalInfo = sourceNode.LexicalInfo;
            var entity = new InternalLocal(local, localType);
            local.Entity = entity;
            CurrentMethod.Locals.Add(local);
            return entity;
        }
		private void AddInternalFieldFor(InternalLocal entity)
		{
			Field field = _enumerator.AddInternalField(UniqueName(entity.Name), entity.Type);
			_mapping[entity] = field.Entity;
		}
Exemple #37
0
		void EmitIndirectAssignment(InternalLocal local, IType typeOnStack)
		{
			var elementType = local.Type.ElementType;
			EmitCastIfNeeded(elementType, typeOnStack);

			var code = GetStoreRefParamCode(elementType);
			if (code == OpCodes.Stobj)
				_il.Emit(code, GetSystemType(elementType));
			else
				_il.Emit(code);
		}
 public Block PrepareEvaluationContextInitialization(IType evaluationContextType)
 {
     this._evaluationContextLocal = this.get_CodeBuilder().DeclareTempLocal(this.CurrentMethodNode, evaluationContextType);
     Block block = new Block();
     block.Add(this.get_CodeBuilder().CreateAssignment(this.CreateEvaluationContextReference(), this.get_CodeBuilder().CreateConstructorInvocation(UtilitiesModule.ConstructorTakingNArgumentsFor(evaluationContextType, 1), this.EvaluationDomainProviderReference())));
     foreach (ParameterDeclaration declaration in this.CurrentMethodNode.get_Parameters())
     {
         block.Add(this.get_CodeBuilder().CreateAssignment(this.CreateEvaluationContextFieldReference(this.GetEvaluationContextField(declaration)), this.get_CodeBuilder().CreateReference(declaration)));
     }
     return block;
 }
		void ImplementByRefICallableCall(
									Method call,
									InternalCallableType type,
									ClassDefinition node,
									CallableSignature signature,
									int byRefCount)
		{			
			MethodInvocationExpression mie = CreateInvokeInvocation(type);
			IParameter[] parameters = signature.Parameters;			
			ReferenceExpression args = CodeBuilder.CreateReference(call.Parameters[0]);
			InternalLocal[] temporaries = new InternalLocal[byRefCount];
			
			int byRefIndex = 0;
			for (int i=0; i<parameters.Length; ++i)
			{				
				SlicingExpression slice = CodeBuilder.CreateSlicing(args.CloneNode(), i);

				IParameter parameter = parameters[i];				
				if (parameter.IsByRef)
				{
					IType tempType = parameter.Type;
					if (tempType.IsByRef)
					{
						tempType = tempType.ElementType;
					}
					temporaries[byRefIndex] = CodeBuilder.DeclareLocal(call,
								"__temp_" + parameter.Name,
								tempType);
								
					call.Body.Add(
						CodeBuilder.CreateAssignment(
						CodeBuilder.CreateReference(temporaries[byRefIndex]),
							CodeBuilder.CreateCast(
								tempType,
								slice)));
						
					mie.Arguments.Add(
						CodeBuilder.CreateReference(
							temporaries[byRefIndex]));
					
					++byRefIndex;
				}
				else
				{
					mie.Arguments.Add(slice);
				}
			}
			
			if (TypeSystemServices.VoidType == signature.ReturnType)
			{
				call.Body.Add(mie);
				PropagateByRefParameterChanges(call, parameters, temporaries);
			}
			else
			{
				InternalLocal invokeReturnValue = CodeBuilder.DeclareLocal(call,
							"__returnValue", signature.ReturnType);
				call.Body.Add(
					CodeBuilder.CreateAssignment(
						CodeBuilder.CreateReference(invokeReturnValue),
						mie));
				PropagateByRefParameterChanges(call, parameters, temporaries);
				call.Body.Add(
					new ReturnStatement(
						CodeBuilder.CreateReference(invokeReturnValue)));
			}
		}
		private bool IsExceptionHandlerVariable(InternalLocal local)
		{
			Declaration originalDeclaration = local.OriginalDeclaration;
			if (originalDeclaration == null) return false;
			return originalDeclaration.ParentNode is ExceptionHandler;
		}
Exemple #41
0
        private void AddInternalFieldFor(InternalLocal entity)
        {
            Field field = _enumerator.AddInternalField(UniqueName(entity.Name), entity.Type);

            _mapping[entity] = field.Entity;
        }
Exemple #42
0
 Expression CloneOrAssignToTemp(InternalLocal temp, Expression operand)
 {
     return null == temp
         ? operand.CloneNode()
         : CodeBuilder.CreateAssignment(
             CodeBuilder.CreateReference(temp),
             operand.CloneNode());
 }
			private ReferenceExpression CreateReference(InternalLocal enteredLoop)
			{
				return CodeBuilder().CreateReference(enteredLoop);
			}
Exemple #44
0
 public Expression CreateDefaultInitializer(LexicalInfo li, InternalLocal local)
 {
     return CreateDefaultInitializer(li, CreateReference(local), local.Type);
 }
Exemple #45
0
 void EmitAssignment(InternalLocal tag, IType typeOnStack)
 {
     // todo: assignment result must be type on the left in the
     // case of casting
     LocalBuilder local = tag.LocalBuilder;
     EmitCastIfNeeded(tag.Type, typeOnStack);
     _il.Emit(OpCodes.Stloc, local);
 }
Exemple #46
0
 public ReferenceExpression CreateLocalReference(string name, InternalLocal entity)
 {
     return CreateTypedReference(name, entity);
 }
Exemple #47
0
        void EmitIndirectAssignment(InternalLocal tag, IType typeOnStack)
        {
            IType et = tag.Type.ElementType;
            EmitCastIfNeeded(et, typeOnStack);

            OpCode code = GetStoreRefParamCode(et);
            if (code == OpCodes.Stobj)
                _il.Emit(code, GetSystemType(et));
            else
                _il.Emit(code);
        }
Exemple #48
0
 public InternalLocal DeclareLocal(Method node, string name, IType type)
 {
     Local local = new Local(node.LexicalInfo, name);
     InternalLocal entity = new InternalLocal(local, type);
     local.Entity = entity;
     node.Locals.Add(local);
     return entity;
 }
Exemple #49
0
        void LoadIndirectLocal(InternalLocal local)
        {
            LoadLocal(local);

            IType et = local.Type.ElementType;
            PopType();
            PushType(et);
            OpCode code = GetLoadRefParamCode(et);
            if (code == OpCodes.Ldobj)
                _il.Emit(code, GetSystemType(et));
            else
                _il.Emit(code);
        }
Exemple #50
0
        private void AddInternalFieldFor(InternalLocal entity)
        {
            Field field = _stateMachineClass.AddInternalField(UniqueName(entity.Name), _methodToStateMachineMapper.MapType(entity.Type));

            _mapping[entity] = (InternalField)field.Entity;
        }
		void PropagateByRefParameterChanges(Method call, IParameter[] parameters, InternalLocal[] temporaries)
		{
			int byRefIndex = 0;
			for (int i=0; i<parameters.Length; ++i)
			{
				if (!parameters[i].IsByRef) continue;
				
				SlicingExpression slice = CodeBuilder.CreateSlicing(
											CodeBuilder.CreateReference(call.Parameters[0]),
											i);						
				call.Body.Add(
					CodeBuilder.CreateAssignment(
						slice,
						CodeBuilder.CreateReference(temporaries[byRefIndex])));
				++byRefIndex;
			}
		}