示例#1
0
 internal void Define(LabelScopeInfo block)
 {
     for (LabelScopeInfo info = block; info != null; info = info.Parent)
     {
         if (info.ContainsTarget(this._node))
         {
             throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Label target already defined: {0}", new object[] { this._node.Name }));
         }
     }
     this.AddDefinition(block);
     block.AddLabelInfo(this._node, this);
     if (this.HasDefinitions && !this.HasMultipleDefinitions)
     {
         foreach (LabelScopeInfo info2 in this._references)
         {
             this.ValidateJump(info2);
         }
     }
     else
     {
         if (this._acrossBlockJump)
         {
             throw new InvalidOperationException("Ambiguous jump");
         }
         this._label = null;
     }
 }
示例#2
0
 internal void Reference(LabelScopeInfo block)
 {
     _references.Add(block);
     if (HasDefinitions)
     {
         ValidateJump(block);
     }
 }
示例#3
0
        private LabelScopeInfo FirstDefinition()
        {
            LabelScopeInfo scope = _definitions as LabelScopeInfo;

            if (scope != null)
            {
                return(scope);
            }
            return(((HashSet <LabelScopeInfo>)_definitions).First());
        }
示例#4
0
 public LightCompiler(int compilationThreshold)
 {
     this._locals = new LocalVariables();
     this._debugInfos = new List<DebugInfo>();
     this._treeLabels = new HybridReferenceDictionary<LabelTarget, LabelInfo>();
     this._labelBlock = new LabelScopeInfo(null, LabelScopeKind.Lambda);
     this._exceptionForRethrowStack = new Stack<ParameterExpression>();
     this._instructions = new InstructionList();
     this._compilationThreshold = (compilationThreshold < 0) ? 0x20 : compilationThreshold;
 }
示例#5
0
        private LabelScopeInfo FirstDefinition()
        {
            LabelScopeInfo info = this._definitions as LabelScopeInfo;

            if (info != null)
            {
                return(info);
            }
            return(((HashSet <LabelScopeInfo>) this._definitions).First <LabelScopeInfo>());
        }
示例#6
0
        private bool DefinedIn(LabelScopeInfo scope)
        {
            if (this._definitions == scope)
            {
                return(true);
            }
            HashSet <LabelScopeInfo> set = this._definitions as HashSet <LabelScopeInfo>;

            return((set != null) && set.Contains(scope));
        }
示例#7
0
        private void ValidateJump(LabelScopeInfo reference)
        {
            // look for a simple jump out
            for (LabelScopeInfo j = reference; j != null; j = j.Parent)
            {
                if (DefinedIn(j))
                {
                    // found it, jump is valid!
                    return;
                }

                if (j.Kind == LabelScopeKind.Filter)
                {
                    break;
                }
            }

            _acrossBlockJump = true;

            if (HasMultipleDefinitions)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Ambiguous jump {0}", _node.Name));
            }

            // We didn't find an outward jump. Look for a jump across blocks
            LabelScopeInfo def    = FirstDefinition();
            LabelScopeInfo common = CommonNode(def, reference, b => b.Parent);

            // Validate that we aren't jumping across a finally
            for (LabelScopeInfo j = reference; j != common; j = j.Parent)
            {
                if (j.Kind == LabelScopeKind.Filter)
                {
                    throw new InvalidOperationException("Control cannot leave filter test");
                }
            }

            // Validate that we aren't jumping into a catch or an expression
            for (LabelScopeInfo j = def; j != common; j = j.Parent)
            {
                if (!j.CanJumpInto)
                {
                    if (j.Kind == LabelScopeKind.Expression)
                    {
                        throw new InvalidOperationException("Control cannot enter an expression");
                    }
                    else
                    {
                        throw new InvalidOperationException("Control cannot enter try");
                    }
                }
            }
        }
示例#8
0
        private bool DefinedIn(LabelScopeInfo scope)
        {
            if (_definitions == scope)
            {
                return(true);
            }

            HashSet <LabelScopeInfo> definitions = _definitions as HashSet <LabelScopeInfo>;

            if (definitions != null)
            {
                return(definitions.Contains(scope));
            }
            return(false);
        }
示例#9
0
 private void AddDefinition(LabelScopeInfo scope)
 {
     if (this._definitions == null)
     {
         this._definitions = scope;
     }
     else
     {
         HashSet <LabelScopeInfo> set = this._definitions as HashSet <LabelScopeInfo>;
         if (set == null)
         {
             this._definitions = set = new HashSet <LabelScopeInfo> {
                 (LabelScopeInfo)this._definitions
             };
         }
         set.Add(scope);
     }
 }
示例#10
0
        private void AddDefinition(LabelScopeInfo scope)
        {
            if (_definitions is null)
            {
                _definitions = scope;
            }
            else
            {
                HashSet <LabelScopeInfo> set = _definitions as HashSet <LabelScopeInfo>;
                if (set is null)
                {
                    _definitions = set = new HashSet <LabelScopeInfo>()
                    {
                        (LabelScopeInfo)_definitions
                    };
                }

                set.Add(scope);
            }
        }
示例#11
0
        private void ValidateJump(LabelScopeInfo reference)
        {
            for (LabelScopeInfo info = reference; info != null; info = info.Parent)
            {
                if (this.DefinedIn(info))
                {
                    return;
                }
                if (info.Kind == LabelScopeKind.Filter)
                {
                    break;
                }
            }
            this._acrossBlockJump = true;
            if (this.HasMultipleDefinitions)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Ambiguous jump {0}", new object[] { this._node.Name }));
            }
            LabelScopeInfo first = this.FirstDefinition();
            LabelScopeInfo info3 = CommonNode <LabelScopeInfo>(first, reference, b => b.Parent);

            for (LabelScopeInfo info4 = reference; info4 != info3; info4 = info4.Parent)
            {
                if (info4.Kind == LabelScopeKind.Filter)
                {
                    throw new InvalidOperationException("Control cannot leave filter test");
                }
            }
            for (LabelScopeInfo info5 = first; info5 != info3; info5 = info5.Parent)
            {
                if (!info5.CanJumpInto)
                {
                    if (info5.Kind == LabelScopeKind.Expression)
                    {
                        throw new InvalidOperationException("Control cannot enter an expression");
                    }
                    throw new InvalidOperationException("Control cannot enter try");
                }
            }
        }
示例#12
0
        internal void Define(LabelScopeInfo block)
        {
            // Prevent the label from being shadowed, which enforces cleaner
            // trees. Also we depend on this for simplicity (keeping only one
            // active IL Label per LabelInfo)
            for (LabelScopeInfo j = block; j != null; j = j.Parent)
            {
                if (j.ContainsTarget(_node))
                {
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Label target already defined: {0}", _node.Name));
                }
            }

            AddDefinition(block);
            block.AddLabelInfo(_node, this);

            // Once defined, validate all jumps
            if (HasDefinitions && !HasMultipleDefinitions)
            {
                foreach (var r in _references)
                {
                    ValidateJump(r);
                }
            }
            else
            {
                // Was just redefined, if we had any across block jumps, they're
                // now invalid
                if (_acrossBlockJump)
                {
                    throw new InvalidOperationException("Ambiguous jump");
                }
                // For local jumps, we need a new IL label
                // This is okay because:
                //   1. no across block jumps have been made or will be made
                //   2. we don't allow the label to be shadowed
                _label = null;
            }
        }
示例#13
0
 internal LabelScopeInfo(LabelScopeInfo parent, LabelScopeKind kind)
 {
     Parent = parent;
     Kind   = kind;
 }
示例#14
0
 public void PushLabelBlock(LabelScopeKind type)
 {
     this._labelBlock = new LabelScopeInfo(this._labelBlock, type);
 }
示例#15
0
 internal LabelScopeInfo(LabelScopeInfo parent, LabelScopeKind kind)
 {
     this.Parent = parent;
     this.Kind   = kind;
 }
示例#16
0
 internal LabelScopeInfo(LabelScopeInfo parent, LabelScopeKind kind)
 {
     this.Parent = parent;
     this.Kind = kind;
 }
示例#17
0
 public void PopLabelBlock(LabelScopeKind kind)
 {
     this._labelBlock = this._labelBlock.Parent;
 }