static int InsertStateGetAndUpdate(CFGContext ctx, int index, BlockKeyType type, uint currentState, uint targetState) { var body = ctx.Graph.Body; if (type == BlockKeyType.Incremental) { body.Instructions.Insert(index + 0, Instruction.Create(OpCodes.Ldloc, ctx.StateVariable)); body.Instructions.Insert(index + 1, Instruction.Create(OpCodes.Dup)); switch (ctx.Random.NextInt32(3)) { case 0: body.Instructions.Insert(index + 2, Instruction.Create(OpCodes.Ldc_I4, (int)(currentState ^ targetState))); body.Instructions.Insert(index + 3, Instruction.Create(OpCodes.Xor)); break; case 1: body.Instructions.Insert(index + 2, Instruction.Create(OpCodes.Ldc_I4, (int)(targetState - currentState))); body.Instructions.Insert(index + 3, Instruction.Create(OpCodes.Add)); break; case 2: body.Instructions.Insert(index + 2, Instruction.Create(OpCodes.Ldc_I4, (int)(currentState - targetState))); body.Instructions.Insert(index + 3, Instruction.Create(OpCodes.Sub)); break; } body.Instructions.Insert(index + 4, Instruction.Create(OpCodes.Stloc, ctx.StateVariable)); return(index + 5); } body.Instructions.Insert(index + 0, Instruction.Create(OpCodes.Ldc_I4, (int)currentState)); body.Instructions.Insert(index + 1, Instruction.Create(OpCodes.Ldc_I4, (int)targetState)); body.Instructions.Insert(index + 2, Instruction.Create(OpCodes.Stloc, ctx.StateVariable)); return(index + 3); }
static int InsertStateGetAndUpdate(CFGContext ctx, int index, BlockKeyType type, uint currentState, uint targetState) { var body = ctx.Graph.Body; if (type == BlockKeyType.Incremental) { body.Instructions.Insert(index + 0, Instruction.Create(OpCodes.Ldloc, ctx.StateVariable)); body.Instructions.Insert(index + 1, Instruction.Create(OpCodes.Dup)); switch (ctx.Random.NextInt32(3)) { case 0: body.Instructions.Insert(index + 2, Instruction.Create(OpCodes.Ldc_I4, (int)(currentState ^ targetState))); body.Instructions.Insert(index + 3, Instruction.Create(OpCodes.Xor)); break; case 1: body.Instructions.Insert(index + 2, Instruction.Create(OpCodes.Ldc_I4, (int)(targetState - currentState))); body.Instructions.Insert(index + 3, Instruction.Create(OpCodes.Add)); break; case 2: body.Instructions.Insert(index + 2, Instruction.Create(OpCodes.Ldc_I4, (int)(currentState - targetState))); body.Instructions.Insert(index + 3, Instruction.Create(OpCodes.Sub)); break; } body.Instructions.Insert(index + 4, Instruction.Create(OpCodes.Stloc, ctx.StateVariable)); return index + 5; } body.Instructions.Insert(index + 0, Instruction.Create(OpCodes.Ldc_I4, (int)currentState)); body.Instructions.Insert(index + 1, Instruction.Create(OpCodes.Ldc_I4, (int)targetState)); body.Instructions.Insert(index + 2, Instruction.Create(OpCodes.Stloc, ctx.StateVariable)); return index + 3; }
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); } } }
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; } } }