#FEATURE by stefan
authorStefan Vogel <sv@exept.de>
Wed, 30 Nov 2016 12:32:29 +0100
changeset 21076 67699e10cae2
parent 21075 d61cf84d605a
child 21077 f8a0edf06bda
#FEATURE by stefan class: ProtoObject added: #shallowCopyOf:
ProtoObject.st
--- a/ProtoObject.st	Wed Nov 30 10:33:19 2016 +0100
+++ b/ProtoObject.st	Wed Nov 30 12:32:29 2016 +0100
@@ -50,6 +50,78 @@
 "
 ! !
 
+!ProtoObject class methodsFor:'helpers'!
+
+shallowCopyOf:anObject
+    "return a copy of anObject with shared subobjects (a shallow copy)
+     i.e. the copy shares referenced instvars with its original."
+
+%{  /* NOCONTEXT */
+    int ninsts, spc, sz;
+    OBJ theCopy;
+    OBJ cls = __qClass(anObject);
+    int flags = __intVal(__ClassInstPtr(cls)->c_flags);
+
+    /*
+     * bail out for special objects ..
+     */
+    if (((flags & ~ARRAYMASK) == 0)
+     && ((flags & ARRAYMASK) != WKPOINTERARRAY)) {
+        sz = __qSize(anObject);
+        __PROTECT__(anObject);
+        __qNew(theCopy, sz);    /* OBJECT ALLOCATION */
+        __UNPROTECT__(anObject);
+        if (theCopy) {
+            cls = __qClass(anObject);
+            spc = __qSpace(theCopy);
+
+            theCopy->o_class = cls; __STORE_SPC(theCopy, cls, spc);
+
+            sz = sz - OHDR_SIZE;
+            if (sz) {
+                char *src, *dst;
+
+                src = (char *)(__InstPtr(anObject)->i_instvars);
+                dst = (char *)(__InstPtr(theCopy)->i_instvars);
+#ifdef bcopy4
+                {
+                    /* care for odd-number of longs */
+                    int nW = sz >> 2;
+
+                    if (sz & 3) {
+                        nW++;
+                    }
+
+                    bcopy4(src, dst, nW);
+                }
+#else
+                bcopy(src, dst, sz);
+#endif
+
+                flags &= ARRAYMASK;
+                if (flags == POINTERARRAY) {
+                    ninsts = __BYTES2OBJS__(sz);
+                } else {
+                    ninsts = __intVal(__ClassInstPtr(cls)->c_ninstvars);
+                }
+                if (ninsts) {
+                    do {
+                        OBJ el;
+
+                        el = __InstPtr(theCopy)->i_instvars[ninsts-1];
+                        __STORE_SPC(theCopy, el, spc);
+                    } while (--ninsts);
+                }
+            }
+            RETURN (theCopy);
+        }
+    }
+%}.
+    "/ fallBack for special objects & memoryAllocation failure case
+
+    ^ self error
+! !
+
 !ProtoObject methodsFor:'error handling'!
 
 doesNotUnderstand:aMessage