mirror of
https://github.com/apple/swift.git
synced 2026-06-20 15:42:51 +02:00
29ea399833
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.
60 lines
1.6 KiB
C++
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
|