Ejemplo n.º 1
0
        private void EmitSwitchBucketsLinearLeaf(ImmutableArray <SwitchBucket> switchBuckets, int low, int high)
        {
            for (int i = low; i < high; i++)
            {
                var nextBucketLabel = new object();
                this.EmitSwitchBucket(switchBuckets[i], nextBucketLabel);

                //  nextBucketLabel:
                _builder.MarkLabel(nextBucketLabel);
            }

            this.EmitSwitchBucket(switchBuckets[high], _fallThroughLabel);
        }
Ejemplo n.º 2
0
        private void EmitHashTableSwitch()
        {
            // Hash value for the key must have already been computed and loaded into keyHash
            Debug.Assert(_keyHash != null);

            // Compute hash value for each case label constant and store the hash buckets
            // into a dictionary indexed by hash value.
            Dictionary <uint, HashBucket> stringHashMap = ComputeStringHashMap(
                _caseLabels,
                _computeStringHashcodeDelegate);

            // Emit conditional jumps to hash buckets.
            // EmitHashBucketJumpTable returns a map from hashValues to hashBucketLabels.
            Dictionary <uint, object> hashBucketLabelsMap = EmitHashBucketJumpTable(stringHashMap);

            // Emit hash buckets
            foreach (var kvPair in stringHashMap)
            {
                // hashBucketLabel:
                //  Emit direct string comparisons for each case label in hash bucket

                _builder.MarkLabel(hashBucketLabelsMap[kvPair.Key]);

                HashBucket hashBucket = kvPair.Value;
                this.EmitNonHashTableSwitch(hashBucket.ToArray());
            }
        }
Ejemplo n.º 3
0
            public override void CloseScope(ILBuilder builder)
            {
                Debug.Assert(_handlers.Count > 1);

                // Fix up the NextExceptionHandler reference of each leader block.
                var tryScope      = _handlers[0];
                var previousBlock = tryScope.LeaderBlock;

                for (int i = 1; i < _handlers.Count; i++)
                {
                    var handlerScope = _handlers[i];
                    var nextBlock    = handlerScope.LeaderBlock;

                    previousBlock.NextExceptionHandler = nextBlock;
                    previousBlock = nextBlock;
                }

                // Generate label for try/catch "leave" target.
                builder.MarkLabel(_endLabel);

                // hide the following code, since it could be reached through the label above.
                builder.DefineHiddenSequencePoint();

                Debug.Assert(builder._currentBlock == builder._labelInfos[_endLabel].bb);

                if (_handlers[1].Type == ScopeType.Finally)
                {
                    // Generate "nop" branch to itself. If this block is unreachable
                    // (because the finally block does not complete), the "nop" will be
                    // replaced by Br_s. On the other hand, if this block is reachable,
                    // the "nop" will be skipped so any "leave" instructions jumping
                    // to this block will jump to the next instead.
                    builder.EmitBranch(ILOpCode.Nop, _endLabel);

                    _handlers[1].SetBlockedByFinallyDestination(_endLabel);
                }
            }