// Emits conditional jumps to hash buckets, returning a map from hashValues to hashBucketLabels. private Dictionary <uint, object> EmitHashBucketJumpTable(Dictionary <uint, HashBucket> stringHashMap) { int count = stringHashMap.Count; var hashBucketLabelsMap = new Dictionary <uint, object>(count); var jumpTableLabels = new KeyValuePair <ConstantValue, object> [count]; int i = 0; foreach (uint hashValue in stringHashMap.Keys) { ConstantValue hashConstant = ConstantValue.Create(hashValue); object hashBucketLabel = new object(); jumpTableLabels[i] = new KeyValuePair <ConstantValue, object>(hashConstant, hashBucketLabel); hashBucketLabelsMap[hashValue] = hashBucketLabel; i++; } // Emit conditional jumps to hash buckets by using an integral switch jump table based on keyHash. var hashBucketJumpTableEmitter = new SwitchIntegralJumpTableEmitter( builder: builder, caseLabels: jumpTableLabels, fallThroughLabel: this.fallThroughLabel, keyTypeCode: Microsoft.Cci.PrimitiveTypeCode.UInt32, keyLocal: keyHash); hashBucketJumpTableEmitter.EmitJumpTable(); return(hashBucketLabelsMap); }
internal void EmitIntegerSwitchJumpTable( KeyValuePair <ConstantValue, object>[] caseLabels, object fallThroughLabel, LocalOrParameter key, Cci.PrimitiveTypeCode keyTypeCode) { Debug.Assert(caseLabels.Length > 0); Debug.Assert(keyTypeCode != Cci.PrimitiveTypeCode.String); // CONSIDER: SwitchIntegralJumpTableEmitter will modify the caseLabels array by sorting it. // CONSIDER: Currently, only purpose of creating this caseLabels array is for Emitting the jump table. // CONSIDER: If this requirement changes, we may want to pass in ArrayBuilder<KeyValuePair<ConstantValue, object>> instead. var emitter = new SwitchIntegralJumpTableEmitter(this, caseLabels, fallThroughLabel, keyTypeCode, key); emitter.EmitJumpTable(); }
/// <summary> /// Primary method for emitting integer switch jump table. /// </summary> /// <param name="caseLabels">switch case labels</param> /// <param name="fallThroughLabel">fall through label for the jump table.</param> /// <param name="key">Local or parameter holding the value to switch on. /// This value has already been loaded onto the execution stack. /// </param> /// <param name="keyTypeCode">Primitive type code of switch key.</param> internal void EmitIntegerSwitchJumpTable( KeyValuePair<ConstantValue, object>[] caseLabels, object fallThroughLabel, LocalOrParameter key, Cci.PrimitiveTypeCode keyTypeCode) { Debug.Assert(caseLabels.Length > 0); Debug.Assert(keyTypeCode != Cci.PrimitiveTypeCode.String); // CONSIDER: SwitchIntegralJumpTableEmitter will modify the caseLabels array by sorting it. // CONSIDER: Currently, only purpose of creating this caseLabels array is for Emitting the jump table. // CONSIDER: If this requirement changes, we may want to pass in ArrayBuilder<KeyValuePair<ConstantValue, object>> instead. var emitter = new SwitchIntegralJumpTableEmitter(this, caseLabels, fallThroughLabel, keyTypeCode, key); emitter.EmitJumpTable(); }
// Emits conditional jumps to hash buckets, returning a map from hashValues to hashBucketLabels. private Dictionary<uint, object> EmitHashBucketJumpTable(Dictionary<uint, HashBucket> stringHashMap) { int count = stringHashMap.Count; var hashBucketLabelsMap = new Dictionary<uint, object>(count); var jumpTableLabels = new KeyValuePair<ConstantValue, object>[count]; int i = 0; foreach (uint hashValue in stringHashMap.Keys) { ConstantValue hashConstant = ConstantValue.Create(hashValue); object hashBucketLabel = new object(); jumpTableLabels[i] = new KeyValuePair<ConstantValue, object>(hashConstant, hashBucketLabel); hashBucketLabelsMap[hashValue] = hashBucketLabel; i++; } // Emit conditional jumps to hash buckets by using an integral switch jump table based on keyHash. var hashBucketJumpTableEmitter = new SwitchIntegralJumpTableEmitter( builder: _builder, caseLabels: jumpTableLabels, fallThroughLabel: _fallThroughLabel, keyTypeCode: Cci.PrimitiveTypeCode.UInt32, key: _keyHash); hashBucketJumpTableEmitter.EmitJumpTable(); return hashBucketLabelsMap; }