예제 #1
0
        private Expression VisitVariable(ParameterExpression node, ExpressionAccess access)
        {
            ParameterExpression boxStorage;

            if (!this._loopLocals.Contains(node))
            {
                LoopVariable  variable;
                LocalVariable variable2;
                if (this._loopVariables.TryGetValue(node, out variable))
                {
                    boxStorage = variable.BoxStorage;
                    this._loopVariables[node] = new LoopVariable(variable.Access | access, boxStorage);
                    goto Label_00A5;
                }
                if (this._outerVariables.TryGetValue(node, out variable2) || ((this._closureVariables != null) && this._closureVariables.TryGetValue(node, out variable2)))
                {
                    boxStorage = variable2.InClosureOrBoxed ? Expression.Parameter(typeof(StrongBox <object>), node.Name) : null;
                    this._loopVariables[node] = new LoopVariable(access, boxStorage);
                    goto Label_00A5;
                }
            }
            return(node);

Label_00A5:
            if (boxStorage == null)
            {
                return(node);
            }
            if ((access & ExpressionAccess.Write) != ExpressionAccess.None)
            {
                return(LightCompiler.Unbox(boxStorage));
            }
            return(Expression.Convert(LightCompiler.Unbox(boxStorage), node.Type));
        }
예제 #2
0
        private Expression VisitVariable(ParameterExpression node, ExpressionAccess access)
        {
            ParameterExpression box;
            LoopVariable        existing;
            LocalVariable       loc;

            if (_loopLocals.Contains(node))
            {
                // local to the loop - not propagated in or out
                return(node);
            }
            else if (_loopVariables.TryGetValue(node, out existing))
            {
                // existing outer variable that we are already tracking
                box = existing.BoxStorage;
                _loopVariables[node] = new LoopVariable(existing.Access | access, box);
            }
            else if (_outerVariables.TryGetValue(node, out loc) ||
                     (_closureVariables != null && _closureVariables.TryGetValue(node, out loc)))
            {
                // not tracking this variable yet, but defined in outer scope and seen for the 1st time
                box = loc.InClosureOrBoxed ? Expression.Parameter(typeof(StrongBox <object>), node.Name) : null;
                _loopVariables[node] = new LoopVariable(access, box);
            }
            else
            {
                // node is a variable defined in a nested lambda -> skip
                return(node);
            }

            if (box != null)
            {
                if ((access & ExpressionAccess.Write) != 0)
                {
                    // compound assignments were reduced:
                    Debug.Assert((access & ExpressionAccess.Read) == 0);

                    // box.Value = (object)rhs
                    return(LightCompiler.Unbox(box));
                }
                else
                {
                    // (T)box.Value
                    return(Expression.Convert(LightCompiler.Unbox(box), node.Type));
                }
            }

            return(node);
        }
예제 #3
0
        private Expression VisitVariable(ParameterExpression node, ExpressionAccess access)
        {
            ParameterExpression box;
            LoopVariable        existing;
            LocalVariable       loc;

            if (_loopVariables.TryGetValue(node, out existing))
            {
                box = existing.BoxStorage;
                _loopVariables[node] = new LoopVariable(existing.Access | access, box);
            }
            else if (_locals.TryGetLocal(node, out loc))
            {
                box = loc.InClosureOrBoxed ? Expression.Parameter(typeof(StrongBox <object>), node.Name) : null;
                _loopVariables[node] = new LoopVariable(access, box);
            }
            else
            {
                // node is a variable defined in a nested lambda -> skip
                return(node);
            }

            if (box != null)
            {
                if ((access & ExpressionAccess.Write) != 0)
                {
                    // compound assignments were reduced:
                    Debug.Assert((access & ExpressionAccess.Read) == 0);

                    // box.Value = (object)rhs
                    return(LightCompiler.Unbox(box));
                }
                else
                {
                    // (T)box.Value
                    return(Expression.Convert(LightCompiler.Unbox(box), node.Type));
                }
            }

            return(node);
        }
예제 #4
0
 public LoopVariable(ExpressionAccess access, ParameterExpression box)
 {
     Access     = access;
     BoxStorage = box;
 }