Stores the per-instance data that all Ruby objects need (frozen?, tainted?, instance_variables, etc) Stored in a lookaside weak hashtable for types that don't implement IRubyObject (i.e. .NET types).
Пример #1
0
        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);
                }
            }
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
 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);
            }
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
 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);
         }
     }
 }
Пример #7
0
 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));
     }
 }
Пример #9
0
 [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));
         }
     }
 }
Пример #10
0
 [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;
 }
Пример #11
0
 public static void SetObjectTaint(ref RubyInstanceData instanceData, bool value) {
     RubyOps.GetInstanceData(ref instanceData).Tainted = value;
 }
Пример #12
0
 public static void FreezeObject(ref RubyInstanceData instanceData) {
     RubyOps.GetInstanceData(ref instanceData).Freeze();
 }
Пример #13
0
 public static bool IsObjectTainted(RubyInstanceData instanceData) {
     return instanceData != null && instanceData.Tainted;
 }
Пример #14
0
 public static bool IsObjectFrozen(RubyInstanceData instanceData) {
     return instanceData != null && instanceData.Frozen;
 }
Пример #15
0
 [Emitted] //RubyTypeBuilder
 public static RubyInstanceData/*!*/ GetInstanceData(ref RubyInstanceData/*!*/ instanceData) {
     if (instanceData == null) {
         Interlocked.CompareExchange(ref instanceData, new RubyInstanceData(), null);
     }
     return instanceData;
 }
Пример #16
0
 internal VariableDebugView(RubyContext/*!*/ context, RubyInstanceData/*!*/ data, string/*!*/ name) {
     _context = context;
     _data = data;
     _name = name;
 }