Skip to content

Commit 1425e32

Browse files
authored
[Runtime] Refactor swift_generic_initWithTake to use shared abstraction (#66379)
We introduced shared abstractions for handling the different tags for the other runtime functions, so we should use them here as well.
1 parent 4325c0a commit 1425e32

File tree

1 file changed

+38
-62
lines changed

1 file changed

+38
-62
lines changed

stdlib/public/runtime/BytecodeLayouts.cpp

Lines changed: 38 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -384,86 +384,62 @@ swift_generic_initWithCopy(swift::OpaqueValue *dest, swift::OpaqueValue *src,
384384
return dest;
385385
}
386386

387-
extern "C" swift::OpaqueValue *
388-
swift_generic_initWithTake(swift::OpaqueValue *dest, swift::OpaqueValue *src,
389-
const Metadata *metadata) {
390-
const uint8_t *typeLayout = metadata->getLayoutString();
391-
size_t size = metadata->vw_size();
392-
393-
memcpy(dest, src, size);
394-
395-
if (SWIFT_LIKELY(metadata->getValueWitnesses()->isBitwiseTakable())) {
396-
return dest;
387+
struct TakeHandler {
388+
static inline void handleMetatype(const Metadata *type, uintptr_t addrOffset,
389+
uint8_t *dest, uint8_t *src) {
390+
if (SWIFT_UNLIKELY(!type->getValueWitnesses()->isBitwiseTakable())) {
391+
type->vw_initializeWithTake(
392+
(OpaqueValue*)((uintptr_t)dest + addrOffset),
393+
(OpaqueValue*)((uintptr_t)src + addrOffset));
394+
}
397395
}
398396

399-
auto offset = layoutStringHeaderSize;
400-
uintptr_t addrOffset = 0;
397+
static inline void handleSinglePayloadEnumSimple(const uint8_t *typeLayout,
398+
size_t &offset,
399+
uintptr_t &addrOffset,
400+
uint8_t *dest,
401+
uint8_t *src) {
402+
::handleSinglePayloadEnumSimple(typeLayout, offset, src, addrOffset);
403+
}
401404

402-
while (true) {
403-
uint64_t skip = readBytes<uint64_t>(typeLayout, offset);
404-
auto tag = static_cast<RefCountingKind>(skip >> 56);
405-
skip &= ~(0xffULL << 56);
406-
addrOffset += skip;
405+
static inline void handleSinglePayloadEnumFN(const uint8_t *typeLayout,
406+
size_t &offset, bool resolved,
407+
uintptr_t &addrOffset,
408+
uint8_t *dest, uint8_t *src) {
409+
::handleSinglePayloadEnumFN(typeLayout, offset, resolved, src, addrOffset);
410+
}
407411

408-
switch (tag) {
409-
case RefCountingKind::UnknownWeak:
412+
static inline void handleReference(RefCountingKind tag, uintptr_t addrOffset,
413+
uint8_t *dest, uint8_t *src) {
414+
if (tag == RefCountingKind::UnknownWeak) {
410415
swift_unknownObjectWeakTakeInit(
411-
(WeakReference*)((uintptr_t)dest + addrOffset),
412-
(WeakReference*)((uintptr_t)src + addrOffset));
413-
break;
414-
case RefCountingKind::Metatype: {
415-
auto *type = readBytes<const Metadata*>(typeLayout, offset);
416-
if (SWIFT_UNLIKELY(!type->getValueWitnesses()->isBitwiseTakable())) {
417-
type->vw_initializeWithTake(
418-
(OpaqueValue*)((uintptr_t)dest + addrOffset),
419-
(OpaqueValue*)((uintptr_t)src + addrOffset));
420-
}
421-
break;
422-
}
423-
case RefCountingKind::Existential: {
416+
(WeakReference*)((uintptr_t)dest + addrOffset),
417+
(WeakReference*)((uintptr_t)src + addrOffset));
418+
} else if (tag == RefCountingKind::Existential) {
424419
auto *type = getExistentialTypeMetadata(
425420
(OpaqueValue*)((uintptr_t)src + addrOffset));
426421
if (SWIFT_UNLIKELY(!type->getValueWitnesses()->isBitwiseTakable())) {
427422
type->vw_initializeWithTake(
428423
(OpaqueValue*)((uintptr_t)dest + addrOffset),
429424
(OpaqueValue*)((uintptr_t)src + addrOffset));
430425
}
431-
break;
432-
}
433-
case RefCountingKind::Resilient: {
434-
auto *type = getResilientTypeMetadata(metadata, typeLayout, offset);
435-
if (SWIFT_UNLIKELY(!type->getValueWitnesses()->isBitwiseTakable())) {
436-
type->vw_initializeWithTake((OpaqueValue*)((uintptr_t)dest + addrOffset),
437-
(OpaqueValue*)((uintptr_t)src + addrOffset));
438-
}
439-
break;
440-
}
441-
442-
case RefCountingKind::SinglePayloadEnumSimple: {
443-
handleSinglePayloadEnumSimple(typeLayout, offset, (uint8_t *)src,
444-
addrOffset);
445-
break;
446426
}
427+
}
428+
};
447429

448-
case RefCountingKind::SinglePayloadEnumFN: {
449-
handleSinglePayloadEnumFN(typeLayout, offset, false, (uint8_t *)src,
450-
addrOffset);
451-
break;
452-
}
430+
extern "C" swift::OpaqueValue *
431+
swift_generic_initWithTake(swift::OpaqueValue *dest, swift::OpaqueValue *src,
432+
const Metadata *metadata) {
433+
size_t size = metadata->vw_size();
453434

454-
case RefCountingKind::SinglePayloadEnumFNResolved: {
455-
handleSinglePayloadEnumFN(typeLayout, offset, true, (uint8_t *)src,
456-
addrOffset);
457-
break;
458-
}
435+
memcpy(dest, src, size);
459436

460-
case RefCountingKind::End:
461-
return dest;
462-
default:
463-
break;
464-
}
437+
if (SWIFT_LIKELY(metadata->getValueWitnesses()->isBitwiseTakable())) {
438+
return dest;
465439
}
466440

441+
handleRefCounts<0, TakeHandler>(metadata, (uint8_t *)dest, (uint8_t *)src);
442+
467443
return dest;
468444
}
469445

0 commit comments

Comments
 (0)