public static object DeepCopy(RubyContext /*!*/ context, object obj) { using (IDisposable handle = _infiniteCopyTracker.TrackObject(obj)) { if (handle == null) { return(RubyExceptions.CreateArgumentError("unable to deep copy recursive structure")); } else { RubyContext ec = RubyUtils.GetExecutionContext(context); if (RubyUtils.IsRubyValueType(obj)) { return(obj); } object copy; // TODO: special case class objects: RubyClass classObject = obj as RubyClass; if (classObject != null) { copy = classObject.Duplicate(); } else { copy = RubySites.Allocate(context, ec.GetClassOf(obj)); } SymbolId[] names = ec.GetInstanceVariableNames(obj); RubyInstanceData newVars = (names.Length > 0) ? ec.GetInstanceData(copy) : null; foreach (SymbolId name in names) { object value; if (!ec.TryGetInstanceVariable(obj, name, out value)) { value = null; } else { value = DeepCopy(context, value); } newVars.SetInstanceVariable(name, value); } if (classObject == null) { // do any special copying needed for library types // TODO: we still need to implement copy semantics for .NET types in general IDuplicable duplicable = copy as IDuplicable; if (duplicable != null) { duplicable.InitializeFrom(obj); } } return(copy); } } }
private void CopyInstanceDataFrom(IRubyObject/*!*/ source, bool copyFrozenState) { // copy instance data, but not the state: var sourceData = source.TryGetInstanceData(); if (sourceData != null) { _instanceData = new RubyInstanceData(); sourceData.CopyInstanceVariablesTo(_instanceData); } // copy flags: SetTaint(this, IsTainted(source)); if (copyFrozenState && IsFrozen(source)) { Freeze(this); } }
internal void CopyInstanceVariablesTo(RubyInstanceData /*!*/ dup) { if (_instanceVars == null) { return; } lock (_instanceVars) { Dictionary <string, object> dupVars = dup.GetInstanceVariables(); foreach (var var in _instanceVars) { dupVars.Add(var.Key, var.Value); } } }
public RubyInstanceData /*!*/ GetValue(object key) { lock (_dict) { RubyInstanceData value; if (_tryGetValue(key, out value)) { return(value); } value = new RubyInstanceData(); _add(key, value); return(value); } }
public static MutableString /*!*/ ObjectToMutableString(RubyContext /*!*/ context, object obj) { using (IDisposable handle = RubyUtils.InfiniteInspectTracker.TrackObject(obj)) { if (handle == null) { return(MutableString.Create("...")); } MutableString str = MutableString.CreateMutable(); str.Append("#<"); str.Append(context.GetClassOf(obj).Name); // Ruby prints 2*object_id for objects str.Append(':'); AppendFormatHexObjectId(str, GetObjectId(context, obj)); // display instance variables RubyInstanceData data = context.TryGetInstanceData(obj); if (data != null) { var vars = data.GetInstanceVariablePairs(); bool first = true; foreach (KeyValuePair <string, object> var in vars) { if (first) { str.Append(" "); first = false; } else { str.Append(", "); } str.Append(var.Key); str.Append("="); str.Append(RubySites.Inspect(context, var.Value)); } } str.Append(">"); return(str); } }
internal void CopyInstanceVariablesTo(RubyInstanceData/*!*/ dup) { if (_instanceVars == null) { return; } lock (_instanceVars) { Dictionary<string, object> dupVars = dup.GetInstanceVariables(); foreach (var var in _instanceVars) { dupVars.Add(var.Key, var.Value); } } }
internal VariableDebugView(RubyContext /*!*/ context, RubyInstanceData /*!*/ data, string /*!*/ name) { _context = context; _data = data; _name = name; }
public bool TryGetValue(object key, out RubyInstanceData value) { lock (_dict) { return(_tryGetValue(key, out value)); } }
[Emitted] //RubyTypeBuilder public static void SerializeObject(RubyInstanceData instanceData, RubyClass/*!*/ immediateClass, SerializationInfo/*!*/ info) { info.AddValue(RubyUtils.SerializationInfoClassKey, immediateClass, typeof(RubyClass)); if (instanceData != null) { string[] instanceNames = instanceData.GetInstanceVariableNames(); foreach (string name in instanceNames) { object value; if (!instanceData.TryGetInstanceVariable(name, out value)) { value = null; } info.AddValue(name, value, typeof(object)); } } }
[Emitted] //RubyTypeBuilder public static void DeserializeObject(out RubyInstanceData/*!*/ instanceData, out RubyClass/*!*/ immediateClass, SerializationInfo/*!*/ info) { immediateClass = (RubyClass)info.GetValue(RubyUtils.SerializationInfoClassKey, typeof(RubyClass)); RubyInstanceData newInstanceData = null; foreach (SerializationEntry entry in info) { if (entry.Name.StartsWith("@")) { if (newInstanceData == null) { newInstanceData = new RubyInstanceData(); } newInstanceData.SetInstanceVariable(entry.Name, entry.Value); } } instanceData = newInstanceData; }
public static void SetObjectTaint(ref RubyInstanceData instanceData, bool value) { RubyOps.GetInstanceData(ref instanceData).Tainted = value; }
public static void FreezeObject(ref RubyInstanceData instanceData) { RubyOps.GetInstanceData(ref instanceData).Freeze(); }
public static bool IsObjectTainted(RubyInstanceData instanceData) { return instanceData != null && instanceData.Tainted; }
public static bool IsObjectFrozen(RubyInstanceData instanceData) { return instanceData != null && instanceData.Frozen; }
[Emitted] //RubyTypeBuilder public static RubyInstanceData/*!*/ GetInstanceData(ref RubyInstanceData/*!*/ instanceData) { if (instanceData == null) { Interlocked.CompareExchange(ref instanceData, new RubyInstanceData(), null); } return instanceData; }
internal VariableDebugView(RubyContext/*!*/ context, RubyInstanceData/*!*/ data, string/*!*/ name) { _context = context; _data = data; _name = name; }