private void EmitFlagValue(IILEmitter emitter, IRng rng)
 {
     if (Constraints != null)
     {
         Constraints.EmitValue(emitter, rng);
     }
     else
     {
         var(signed, bytes) = IntConstraints.GetProps(Flag.Field.FieldType.ElementType);
         emitter.Const(Value.Value, bytes, signed);
     }
 }
        public void EmitChecker(IILEmitter emitter, IRng rng, Instruction normalFlowTarget)
        {
            var fv = Flag.Field;

            emitter.Emit(OpCodes.Ldarg_0);
            emitter.Emit(OpCodes.Ldfld, emitter.Importer.Import(fv));
            if (Constraints != null)
            {
                emitter.NumericConversion(fv.FieldType.ElementType, Constraints.ElementType, false);
                Constraints.EmitChecker(rng, emitter, normalFlowTarget);
            }
            else
            {
                var(signed, bytes) = IntConstraints.GetProps(Flag.Field.FieldType.ElementType);
                emitter.Const(Value.Value, bytes, signed);
                emitter.Emit(OpCodes.Bne_Un, normalFlowTarget);
            }
        }
        protected InjectedFeature(InjectableMethod method, Var output, IRng rng)
        {
            Method = method;
            Output = output;
            var  maxFlags = 15;
            bool overlaps;

            do
            {
                var flag = method.Type.GetOrAddFlag(rng);
                var(signed, bytes) = IntConstraints.GetProps(flag.Field.FieldType.ElementType);
                var maxOverlaps = 10;
                do
                {
                    long?          value;
                    IntConstraints constraints;
                    if (rng.NextBoolean())
                    {
                        value       = null;
                        constraints = IntConstraints.Generate(rng, bytes, signed);
                    }
                    else
                    {
                        value       = IntConstraints.NextInt(rng, bytes, signed);
                        constraints = null;
                    }

                    overlaps = false;
                    foreach (var feature in flag.Features)
                    {
                        if (feature.Value.HasValue)
                        {
                            if (value.HasValue && feature.Value.Value == value.Value)
                            {
                                overlaps = true;
                            }
                            else if (constraints != null && constraints.Contains(feature.Value.Value))
                            {
                                overlaps = true;
                            }
                        }
                        else
                        {
                            if (value.HasValue && feature.Constraints.Contains(value.Value))
                            {
                                overlaps = true;
                            }
                            else if (constraints != null && constraints.Overlaps(feature.Constraints))
                            {
                                overlaps = true;
                            }
                        }

                        if (overlaps)
                        {
                            break;
                        }
                    }

                    if (!overlaps)
                    {
                        Value       = value;
                        Constraints = constraints;
                        flag.AddFeature(this);
                        Flag = flag;
                        break;
                    }
                } while (maxOverlaps-- > 0);
            } while (overlaps && maxFlags-- > 0);

            if (overlaps)
            {
                throw new Exception("could not create flag for injected feature");
            }
        }