public LocalCtxFrame CreateNext() { var nextFrame = new LocalCtxFrame(this); this.Next = nextFrame; return(nextFrame); }
public LocalCtxFrame(LocalCtxFrame prev) { this.Prev = prev; this.Next = null; this.Depth = prev.Depth + 1; this.Locals = new HashSet <ObjPtr>(); }
private ObjPtr SelectObject(LocalCtxFrame frame, bool useStatics = true) { List <ObjPtr> ptrs; if (useStatics) { ptrs = frame.Locals.Concat(_ctx.Statics).Distinct().ToList(); } else { ptrs = frame.Locals.ToList(); } if (ptrs.Count == 0) { return(ObjPtr.Zero); } else { return(this.SelectDeepObject(ptrs[_rnd.Next(0, ptrs.Count)])); } //if (_rnd.Next(100) > 50 && useStatics) //{ // if (_ctx.Statics.Count > 0) // return this.SelectDeepObject(_ctx.Statics.Skip(_rnd.Next(0, _ctx.Statics.Count)).First()); // else // return ObjPtr.Zero; //} //else //{ // if (frame.Locals.Count > 0) // return this.SelectDeepObject(frame.Locals.Skip(_rnd.Next(0, frame.Locals.Count)).First()); // else // return ObjPtr.Zero; //} }
private ObjPtr PerformAction(MutatorActionKind actionKind, ref LocalCtxFrame frame) { ObjPtr ptr; switch (actionKind) { case MutatorActionKind.None: ptr = ObjPtr.Zero; break; case MutatorActionKind.Call: frame = frame.CreateNext(); ptr = ObjPtr.Zero; break; case MutatorActionKind.Return: frame = frame.ResumePrev(); ptr = ObjPtr.Zero; break; case MutatorActionKind.Newobj: frame.Locals.Add(ptr = _ctx.Runtime.AllocRandomObj(_rnd)); break; case MutatorActionKind.PutStatic: { lock (_ctx.Statics) { if (frame.Locals.Count > 0) { _ctx.Statics.Add(ptr = frame.Locals.Skip(_rnd.Next(0, frame.Locals.Count)).First()); } else { ptr = ObjPtr.Zero; } } } break; case MutatorActionKind.ChangeStatic: { lock (_ctx.Statics) { if (_ctx.Statics.Count > 0 && frame.Locals.Count > 0) { _ctx.Statics.Remove(_ctx.Statics.Skip(_rnd.Next(0, _ctx.Statics.Count)).First()); _ctx.Statics.Add(ptr = frame.Locals.Skip(_rnd.Next(0, frame.Locals.Count)).First()); } else { ptr = ObjPtr.Zero; } } } break; case MutatorActionKind.EraseStatic: { lock (_ctx.Statics) { if (_ctx.Statics.Count > 0) { _ctx.Statics.Remove(ptr = _ctx.Statics.Skip(_rnd.Next(0, _ctx.Statics.Count)).First()); } else { ptr = ObjPtr.Zero; } } } break; case MutatorActionKind.PutRef: { lock (_ctx.Statics) { ptr = this.SelectObject(frame); if (ptr.value != IntPtr.Zero) { _refBuffer.Value = _ctx.Runtime.ObjToBlock(this.SelectObject(frame, useStatics: false)).value; var refs = _ctx.Runtime.GetRefs(ptr); var field = refs.FirstOrDefault(f => { f.GetValue(_ctx.Runtime.ObjToBlock(ptr), _refBuffer.buffPtr); return(_refBuffer.Value == IntPtr.Zero); }); if (field != null) { field.SetValue(_ctx.Runtime.ObjToBlock(ptr), _refBuffer.buffPtr); } else { refs[_rnd.Next(0, refs.Length)].SetValue(_ctx.Runtime.ObjToBlock(ptr), _refBuffer.buffPtr); } } } } break; case MutatorActionKind.ChangeRef: { lock (_ctx.Statics) { ptr = this.SelectObject(frame); if (ptr.value != IntPtr.Zero) { _refBuffer.Value = _ctx.Runtime.ObjToBlock(this.SelectObject(frame, useStatics: false)).value; var refs = _ctx.Runtime.GetRefs(ptr); refs[_rnd.Next(0, refs.Length)].SetValue(_ctx.Runtime.ObjToBlock(ptr), _refBuffer.buffPtr); } } } break; case MutatorActionKind.EraseRef: { lock (_ctx.Statics) { ptr = this.SelectObject(frame); if (ptr.value != IntPtr.Zero) { var refs = _ctx.Runtime.GetRefs(ptr); var field = refs.FirstOrDefault(f => { f.GetValue(_ctx.Runtime.ObjToBlock(ptr), _refBuffer.buffPtr); return(_refBuffer.Value != IntPtr.Zero); }); _refBuffer.Value = IntPtr.Zero; if (field != null) { field.SetValue(_ctx.Runtime.ObjToBlock(ptr), _refBuffer.buffPtr); } } } } break; default: throw new NotImplementedException("Unknown action " + actionKind); } return(ptr); }