public static bool TryDuplicateObject(RubyContext /*!*/ context, object obj, bool cloneSemantics, out object copy) { // Ruby value types can't be cloned if (RubyUtils.IsRubyValueType(obj)) { copy = null; return(false); } IDuplicable clonable = obj as IDuplicable; if (clonable != null) { copy = clonable.Duplicate(context, cloneSemantics); } else { // .NET classes and library clases that doesn't implement IDuplicable: copy = RubySites.Allocate(context.GetClassOf(obj)); context.CopyInstanceData(obj, copy, cloneSemantics); } // TODO: optimize _InitializeCopySharedSite.Target(_InitializeCopySharedSite, context, copy, obj); if (cloneSemantics) { context.FreezeObjectBy(copy, obj); } return(true); }
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); } } }
public static MutableString Digest(RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ str) { // TODO: new? object obj = RubySites.Allocate(self); // TODO: check obj return(DigestSite.Target(DigestSite, self.Context, obj, str)); }
public static MutableString InflateStream(RubyClass /*!*/ self, MutableString zstring) { object obj = RubySites.Allocate(self); return(InflateSite.Target(InflateSite, self.Context, obj, zstring)); }