Files
swift-mirror/lib/IRGen/ExistentialMetadataVisitor.h
T
Doug Gregor 29ea399833 [Embedded] Reimplement dynamic casting for Embedded Swift
The Embedded Swift dynamic casting logic was getting a bit tangled, and
used some heuristics for figuring out the existential representation
that didn't always work, e.g., with class-bound types.

Reimplement the entire thing using the same general approach that the
non-Embedded runtime uses, albeit simplified greatly because Embedded
Swift doesn't permit casting to existential types (only *from*
existential types). The new implementation correctly unwraps all levels
of existential, short-circuits where appropriate, and "takes" wherever
possible.

This change does require emitting some more metadata than we did
before, because it is necessary to handle the different existential
representations correctly. Previously, the compiler would pass a NULL
pointer as the "source" metadata to `swift_dynamicCast`, then try to
figure out what it was given by inspecting the source pointer. This is
insufficient for distinguishing the various existential representations
(opaque, class-bound, error) and relied on heuristics. Start passing
destination metadata to this function, just as we do in non-Embedded
Swift. This means we'll end up generating some more metadata for
existential types (like `any P`) that we wouldn't have before, but
it's still pay-per-use and they are relatively small. All of the other
metadata that can flow here will already have been created for other
reasons, e.g., because classes already have it in their vtable.

This also extends the metadata associated with existential types by one
more word (from 2 to 3). The new word is used to provide the
existential representation, which is needed for dynamic casting as
described above.
2026-04-28 15:07:56 -07:00

60 lines
1.6 KiB
C++

//===--- ExistentialMetadataVisitor.h - CRTP for 'any' metadata -*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// A CRTP class useful for laying out existential metadata.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_IRGEN_EXISTENTIALMETADATALAYOUT_H
#define SWIFT_IRGEN_EXISTENTIALMETADATALAYOUT_H
#include "swift/AST/Type.h"
namespace swift {
namespace irgen {
/// A CRTP class for laying out existential metadata.
///
/// This produces an object corresponding to a ExistentialTypeMetadata type.
/// It does not itself doing anything special for metadata templates.
template <class Impl> struct ExistentialMetadataVisitor
: public MetadataVisitor<Impl> {
using super = MetadataVisitor<Impl>;
protected:
using super::asImpl;
Type Target;
ExistentialMetadataVisitor(IRGenModule &IGM, Type target)
: super(IGM), Target(target) {
assert(target->isAnyExistentialType());
}
public:
void embeddedLayout() {
// The embedded layout consists of:
// -1 : vwt
// 0 : metadata flags
// 1 : existential representation
super::layout();
asImpl().addEmbeddedRepresentation();
}
};
} // end namespace irgen
} // end namespace swift
#endif