@@ -25,7 +25,20 @@ namespace swift {
2525namespace metadataimpl {
2626
2727// / A common base class for opaque-existential and class-existential boxes.
28- template <typename Impl> struct SWIFT_LIBRARY_VISIBILITY ExistentialBoxBase {};
28+ template <typename Impl>
29+ struct SWIFT_LIBRARY_VISIBILITY ExistentialBoxBase {
30+ template <class Container , class ... A>
31+ static void copyBytes (Container *dest, Container *src, A... args) {
32+ memcpy (dest, src, src->getContainerStride (args...));
33+ }
34+
35+ template <class Container , class ... A>
36+ static void copyTypeBytes (Container *dest, Container *src, A...args) {
37+ auto valueBytes = src->getValueSize ();
38+ auto toCopy = src->getContainerStride (args...) - valueBytes;
39+ memcpy ((char *)dest + valueBytes, (char *)src + valueBytes, toCopy);
40+ }
41+ };
2942
3043// / A common base class for fixed and non-fixed opaque-existential box
3144// / implementations.
@@ -83,7 +96,7 @@ struct SWIFT_LIBRARY_VISIBILITY OpaqueExistentialBoxBase
8396 template <class Container , class ... A>
8497 static Container *initializeWithCopy (Container *dest, Container *src,
8598 A... args) {
86- src-> copyTypeInto (dest, args...);
99+ copyTypeBytes (dest, src , args...);
87100 auto *type = src->getType ();
88101 auto *vwt = type->getValueWitnesses ();
89102
@@ -104,10 +117,7 @@ struct SWIFT_LIBRARY_VISIBILITY OpaqueExistentialBoxBase
104117 template <class Container , class ... A>
105118 static Container *initializeWithTake (Container *dest, Container *src,
106119 A... args) {
107- src->copyTypeInto (dest, args...);
108- auto from = src->getBuffer (args...);
109- auto to = dest->getBuffer (args...);
110- memcpy (to, from, sizeof (ValueBuffer));
120+ copyBytes (dest, src, args...);
111121 return dest;
112122 }
113123
@@ -151,7 +161,7 @@ struct SWIFT_LIBRARY_VISIBILITY OpaqueExistentialBoxBase
151161 // Move dest value aside so we can destroy it later.
152162 destType->vw_initializeWithTake (opaqueTmpBuffer, destValue);
153163
154- src-> copyTypeInto (dest, args...);
164+ copyTypeBytes (dest, src , args...);
155165 if (srcVwt->isValueInline ()) {
156166 // Inline src value.
157167
@@ -172,7 +182,7 @@ struct SWIFT_LIBRARY_VISIBILITY OpaqueExistentialBoxBase
172182 auto *destRef =
173183 *reinterpret_cast <HeapObject **>(dest->getBuffer (args...));
174184
175- src-> copyTypeInto (dest, args...);
185+ copyTypeBytes (dest, src , args...);
176186 if (srcVwt->isValueInline ()) {
177187
178188 // initWithCopy.
@@ -239,7 +249,7 @@ struct SWIFT_LIBRARY_VISIBILITY OpaqueExistentialBoxBase
239249 // Move dest value aside.
240250 destType->vw_initializeWithTake (opaqueTmpBuffer, destValue);
241251
242- src-> copyTypeInto (dest, args...);
252+ copyTypeBytes (dest, src , args...);
243253 if (srcVwt->isValueInline ()) {
244254 // Inline src value.
245255
@@ -260,7 +270,7 @@ struct SWIFT_LIBRARY_VISIBILITY OpaqueExistentialBoxBase
260270 auto *destRef =
261271 *reinterpret_cast <HeapObject **>(dest->getBuffer (args...));
262272
263- src-> copyTypeInto (dest, args...);
273+ copyTypeBytes (dest, src , args...);
264274 if (srcVwt->isValueInline ()) {
265275 // initWithCopy.
266276
@@ -291,12 +301,20 @@ template <unsigned NumWitnessTables>
291301struct SWIFT_LIBRARY_VISIBILITY FixedOpaqueExistentialContainer {
292302 OpaqueExistentialContainer Header;
293303 const void *WitnessTables[NumWitnessTables];
304+
305+ static size_t getValueSize () {
306+ return sizeof (Header.Buffer );
307+ }
294308};
295309// We need to be able to instantiate for NumWitnessTables==0, which
296310// requires an explicit specialization.
297311template <>
298312struct FixedOpaqueExistentialContainer <0 > {
299313 OpaqueExistentialContainer Header;
314+
315+ static size_t getValueSize () {
316+ return sizeof (Header.Buffer );
317+ }
300318};
301319
302320// / A box implementation class for an opaque existential type with
@@ -311,10 +329,7 @@ struct SWIFT_LIBRARY_VISIBILITY OpaqueExistentialBox
311329 ValueBuffer *getBuffer () {
312330 return &this ->Header .Buffer ;
313331 }
314- void copyTypeInto (Container *dest) const {
315- this ->Header .copyTypeInto (&dest->Header , NumWitnessTables);
316- }
317-
332+
318333 static size_t getContainerStride () {
319334 return sizeof (Container);
320335 }
@@ -355,9 +370,6 @@ struct SWIFT_LIBRARY_VISIBILITY NonFixedOpaqueExistentialBox
355370 ValueBuffer *getBuffer (const Metadata *self) {
356371 return &Header.Buffer ;
357372 }
358- void copyTypeInto (Container *dest, const Metadata *self) {
359- Header.copyTypeInto (&dest->Header , getNumWitnessTables (self));
360- }
361373
362374 static unsigned getNumWitnessTables (const Metadata *self) {
363375 auto castSelf = static_cast <const ExistentialTypeMetadata*>(self);
@@ -377,7 +389,11 @@ struct SWIFT_LIBRARY_VISIBILITY NonFixedOpaqueExistentialBox
377389 }
378390
379391 static size_t getContainerStride (const Metadata *self) {
380- return getStride (getNumWitnessTables (self));
392+ return self->vw_stride ();
393+ }
394+
395+ static size_t getValueSize () {
396+ return sizeof (Header.Buffer );
381397 }
382398 };
383399
@@ -411,28 +427,25 @@ struct SWIFT_LIBRARY_VISIBILITY ClassExistentialBoxBase
411427 template <class Container , class ... A>
412428 static Container *initializeWithCopy (Container *dest, Container *src,
413429 A... args) {
414- src->copyTypeInto (dest, args...);
415430 auto newValue = *src->getValueSlot ();
416- *dest-> getValueSlot () = newValue ;
431+ copyBytes (dest, src, args...) ;
417432 swift_unknownObjectRetain (newValue);
418433 return dest;
419434 }
420435
421436 template <class Container , class ... A>
422437 static Container *initializeWithTake (Container *dest, Container *src,
423438 A... args) {
424- src->copyTypeInto (dest, args...);
425- *dest->getValueSlot () = *src->getValueSlot ();
439+ copyBytes (dest, src, args...);
426440 return dest;
427441 }
428442
429443 template <class Container , class ... A>
430444 static Container *assignWithCopy (Container *dest, Container *src,
431445 A... args) {
432- src->copyTypeInto (dest, args...);
433446 auto newValue = *src->getValueSlot ();
434447 auto oldValue = *dest->getValueSlot ();
435- *dest-> getValueSlot () = newValue ;
448+ copyBytes (dest, src, args...) ;
436449 swift_unknownObjectRetain (newValue);
437450 swift_unknownObjectRelease (oldValue);
438451 return dest;
@@ -441,10 +454,8 @@ struct SWIFT_LIBRARY_VISIBILITY ClassExistentialBoxBase
441454 template <class Container , class ... A>
442455 static Container *assignWithTake (Container *dest, Container *src,
443456 A... args) {
444- src->copyTypeInto (dest, args...);
445- auto newValue = *src->getValueSlot ();
446457 auto oldValue = *dest->getValueSlot ();
447- *dest-> getValueSlot () = newValue ;
458+ copyBytes (dest, src, args...) ;
448459 swift_unknownObjectRelease (oldValue);
449460 return dest;
450461 }
@@ -470,10 +481,6 @@ struct SWIFT_LIBRARY_VISIBILITY ClassExistentialBox : ClassExistentialBoxBase {
470481 ClassExistentialContainer Header;
471482 const void *TypeInfo[NumWitnessTables];
472483
473- void copyTypeInto (Container *dest) const {
474- for (unsigned i = 0 ; i != NumWitnessTables; ++i)
475- dest->TypeInfo [i] = TypeInfo[i];
476- }
477484 void **getValueSlot () { return &Header.Value ; }
478485 void * const *getValueSlot () const { return &Header.Value ; }
479486
@@ -501,10 +508,6 @@ struct SWIFT_LIBRARY_VISIBILITY NonFixedClassExistentialBox
501508 return castSelf->Flags .getNumWitnessTables ();
502509 }
503510
504- void copyTypeInto (Container *dest, const Metadata *self) {
505- Header.copyTypeInto (&dest->Header , getNumWitnessTables (self));
506- }
507-
508511 void **getValueSlot () { return &Header.Value ; }
509512 void * const *getValueSlot () const { return &Header.Value ; }
510513
@@ -520,7 +523,7 @@ struct SWIFT_LIBRARY_VISIBILITY NonFixedClassExistentialBox
520523 return getSize (numWitnessTables);
521524 }
522525 static size_t getContainerStride (const Metadata *self) {
523- return getStride ( getNumWitnessTables ( self) );
526+ return self-> vw_stride ( );
524527 }
525528 };
526529 using type = Container;
@@ -540,32 +543,28 @@ struct SWIFT_LIBRARY_VISIBILITY ExistentialMetatypeBoxBase
540543 template <class Container , class ... A>
541544 static Container *initializeWithCopy (Container *dest, Container *src,
542545 A... args) {
543- src->copyTypeInto (dest, args...);
544- *dest->getValueSlot () = *src->getValueSlot ();
545- return dest;
546+ copyBytes (dest, src, args...);
547+ return dest;
546548 }
547549
548550 template <class Container , class ... A>
549551 static Container *initializeWithTake (Container *dest, Container *src,
550552 A... args) {
551- src->copyTypeInto (dest, args...);
552- *dest->getValueSlot () = *src->getValueSlot ();
553+ copyBytes (dest, src, args...);
553554 return dest;
554555 }
555556
556557 template <class Container , class ... A>
557558 static Container *assignWithCopy (Container *dest, Container *src,
558559 A... args) {
559- src->copyTypeInto (dest, args...);
560- *dest->getValueSlot () = *src->getValueSlot ();
560+ copyBytes (dest, src, args...);
561561 return dest;
562562 }
563563
564564 template <class Container , class ... A>
565565 static Container *assignWithTake (Container *dest, Container *src,
566566 A... args) {
567- src->copyTypeInto (dest, args...);
568- *dest->getValueSlot () = *src->getValueSlot ();
567+ copyBytes (dest, src, args...);
569568 return dest;
570569 }
571570
@@ -593,10 +592,6 @@ struct SWIFT_LIBRARY_VISIBILITY ExistentialMetatypeBox
593592 ExistentialMetatypeContainer Header;
594593 const void *TypeInfo[NumWitnessTables];
595594
596- void copyTypeInto (Container *dest) const {
597- for (unsigned i = 0 ; i != NumWitnessTables; ++i)
598- dest->TypeInfo [i] = TypeInfo[i];
599- }
600595 const Metadata **getValueSlot () { return &Header.Value ; }
601596 const Metadata * const *getValueSlot () const { return &Header.Value ; }
602597
@@ -624,10 +619,6 @@ struct SWIFT_LIBRARY_VISIBILITY NonFixedExistentialMetatypeBox
624619 return castSelf->Flags .getNumWitnessTables ();
625620 }
626621
627- void copyTypeInto (Container *dest, const Metadata *self) {
628- Header.copyTypeInto (&dest->Header , getNumWitnessTables (self));
629- }
630-
631622 const Metadata **getValueSlot () { return &Header.Value ; }
632623 const Metadata * const *getValueSlot () const { return &Header.Value ; }
633624
@@ -643,7 +634,7 @@ struct SWIFT_LIBRARY_VISIBILITY NonFixedExistentialMetatypeBox
643634 return getSize (numWitnessTables);
644635 }
645636 static size_t getContainerStride (const Metadata *self) {
646- return getStride ( getNumWitnessTables ( self) );
637+ return self-> vw_stride ( );
647638 }
648639 };
649640 using type = Container;
0 commit comments