Ejemplo n.º 1
0
        static uint InsertStateGetAndUpdate(CFGContext ctx, ref int index, BlockKeyType type, ref CFGState currentState, CFGState?targetState)
        {
            var body = ctx.Graph.Body;

            if (type == BlockKeyType.Incremental)
            {
                // Incremental

                if (targetState == null)
                {
                    // Randomly update and get state
                    int  updateId    = ctx.Random.NextInt32(3);
                    uint targetValue = ctx.Random.NextUInt32();

                    int getId = ctx.Random.NextInt32(3);
                    var fl    = CFGState.EncodeFlag(false, updateId, getId);
                    var incr  = currentState.GetIncrementalUpdate(updateId, targetValue);
                    currentState.UpdateExplicit(updateId, targetValue);

                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldloca, ctx.StateVariable));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)fl));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4, (int)incr));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Call, ctx.Ctx.CfgCtxNext));

                    return(currentState.Get(getId));
                }
                // Scan for updated state
                int[] stateIds = { 0, 1, 2, 3 };
                ctx.Random.Shuffle(stateIds);
                int  i        = 0;
                uint getValue = 0;
                foreach (var stateId in stateIds)
                {
                    // There must be at least one update&get
                    if (currentState.Get(stateId) == targetState.Value.Get(stateId) &&
                        i != stateIds.Length - 1)
                    {
                        i++;
                        continue;
                    }

                    uint targetValue = targetState.Value.Get(stateId);
                    int  getId       = ctx.Random.NextInt32(3);
                    var  fl          = CFGState.EncodeFlag(false, stateId, getId);
                    var  incr        = currentState.GetIncrementalUpdate(stateId, targetValue);
                    currentState.UpdateExplicit(stateId, targetValue);

                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldloca, ctx.StateVariable));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)fl));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4, (int)incr));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Call, ctx.Ctx.CfgCtxNext));

                    i++;
                    if (i == stateIds.Length)
                    {
                        getValue = currentState.Get(getId);
                    }
                    else
                    {
                        body.Instructions.Insert(index++, Instruction.Create(OpCodes.Pop));
                    }
                }
                return(getValue);
            }
            else
            {
                // Explicit

                if (targetState == null)
                {
                    // Create new exit state from random seed
                    var seed = ctx.Random.NextUInt32();
                    currentState = new CFGState(seed);
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldloca, ctx.StateVariable));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Dup));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4, (int)seed));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Call, ctx.Ctx.CfgCtxCtor));

                    // Randomly get state
                    int  updateId    = ctx.Random.NextInt32(3);
                    uint targetValue = ctx.Random.NextUInt32();

                    int getId = ctx.Random.NextInt32(3);
                    var fl    = CFGState.EncodeFlag(false, updateId, getId);
                    var incr  = currentState.GetIncrementalUpdate(updateId, targetValue);
                    currentState.UpdateExplicit(updateId, targetValue);

                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)fl));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4, (int)incr));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Call, ctx.Ctx.CfgCtxNext));

                    return(currentState.Get(getId));
                }
                else
                {
                    // Scan for updated state
                    int[] stateIds = { 0, 1, 2, 3 };
                    ctx.Random.Shuffle(stateIds);
                    int  i        = 0;
                    uint getValue = 0;
                    foreach (var stateId in stateIds)
                    {
                        uint targetValue = targetState.Value.Get(stateId);
                        int  getId       = ctx.Random.NextInt32(3);
                        var  fl          = CFGState.EncodeFlag(true, stateId, getId);
                        currentState.UpdateExplicit(stateId, targetValue);

                        body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldloca, ctx.StateVariable));
                        body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)fl));
                        body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4, (int)targetValue));
                        body.Instructions.Insert(index++, Instruction.Create(OpCodes.Call, ctx.Ctx.CfgCtxNext));

                        i++;
                        if (i == stateIds.Length)
                        {
                            getValue = targetState.Value.Get(getId);
                        }
                        else
                        {
                            body.Instructions.Insert(index++, Instruction.Create(OpCodes.Pop));
                        }
                    }
                    return(getValue);
                }
            }
        }
Ejemplo n.º 2
0
        static uint InsertStateGetAndUpdate(CFGContext ctx, ref int index, BlockKeyType type, ref CFGState currentState, CFGState? targetState)
        {
            var body = ctx.Graph.Body;

            if (type == BlockKeyType.Incremental) {
                // Incremental

                if (targetState == null) {
                    // Randomly update and get state
                    int updateId = ctx.Random.NextInt32(3);
                    uint targetValue = ctx.Random.NextUInt32();

                    int getId = ctx.Random.NextInt32(3);
                    var fl = CFGState.EncodeFlag(false, updateId, getId);
                    var incr = currentState.GetIncrementalUpdate(updateId, targetValue);
                    currentState.UpdateExplicit(updateId, targetValue);

                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldloca, ctx.StateVariable));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)fl));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4, (int)incr));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Call, ctx.Ctx.CfgCtxNext));

                    return currentState.Get(getId);
                }
                // Scan for updated state
                int[] stateIds = { 0, 1, 2, 3 };
                ctx.Random.Shuffle(stateIds);
                int i = 0;
                uint getValue = 0;
                foreach (var stateId in stateIds) {
                    // There must be at least one update&get
                    if (currentState.Get(stateId) == targetState.Value.Get(stateId) &&
                        i != stateIds.Length - 1) {
                        i++;
                        continue;
                    }

                    uint targetValue = targetState.Value.Get(stateId);
                    int getId = ctx.Random.NextInt32(3);
                    var fl = CFGState.EncodeFlag(false, stateId, getId);
                    var incr = currentState.GetIncrementalUpdate(stateId, targetValue);
                    currentState.UpdateExplicit(stateId, targetValue);

                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldloca, ctx.StateVariable));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)fl));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4, (int)incr));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Call, ctx.Ctx.CfgCtxNext));

                    i++;
                    if (i == stateIds.Length)
                        getValue = currentState.Get(getId);
                    else
                        body.Instructions.Insert(index++, Instruction.Create(OpCodes.Pop));
                }
                return getValue;
            }
            else {
                // Explicit

                if (targetState == null) {
                    // Create new exit state from random seed
                    var seed = ctx.Random.NextUInt32();
                    currentState = new CFGState(seed);
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldloca, ctx.StateVariable));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Dup));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4, (int)seed));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Call, ctx.Ctx.CfgCtxCtor));

                    // Randomly get state
                    int updateId = ctx.Random.NextInt32(3);
                    uint targetValue = ctx.Random.NextUInt32();

                    int getId = ctx.Random.NextInt32(3);
                    var fl = CFGState.EncodeFlag(false, updateId, getId);
                    var incr = currentState.GetIncrementalUpdate(updateId, targetValue);
                    currentState.UpdateExplicit(updateId, targetValue);

                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)fl));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4, (int)incr));
                    body.Instructions.Insert(index++, Instruction.Create(OpCodes.Call, ctx.Ctx.CfgCtxNext));

                    return currentState.Get(getId);
                }
                else {
                    // Scan for updated state
                    int[] stateIds = { 0, 1, 2, 3 };
                    ctx.Random.Shuffle(stateIds);
                    int i = 0;
                    uint getValue = 0;
                    foreach (var stateId in stateIds) {
                        uint targetValue = targetState.Value.Get(stateId);
                        int getId = ctx.Random.NextInt32(3);
                        var fl = CFGState.EncodeFlag(true, stateId, getId);
                        currentState.UpdateExplicit(stateId, targetValue);

                        body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldloca, ctx.StateVariable));
                        body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)fl));
                        body.Instructions.Insert(index++, Instruction.Create(OpCodes.Ldc_I4, (int)targetValue));
                        body.Instructions.Insert(index++, Instruction.Create(OpCodes.Call, ctx.Ctx.CfgCtxNext));

                        i++;
                        if (i == stateIds.Length)
                            getValue = targetState.Value.Get(getId);
                        else
                            body.Instructions.Insert(index++, Instruction.Create(OpCodes.Pop));
                    }
                    return getValue;
                }
            }
        }