Skip to content

Commit cb1379f

Browse files
Merge pull request #5203 from swiftwasm/main
[pull] swiftwasm from main
2 parents e0663cc + d951335 commit cb1379f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1194
-126
lines changed

docs/HowToGuides/GettingStarted.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ toolchain as a one-off, there are a couple of differences:
187187

188188
### Spot check dependencies
189189

190-
* Run `cmake --version`; this should be 3.19.6 or higher.
190+
* Run `cmake --version`; this should be at least 3.19.6 (3.22.2 if you want to generate an Xcode project on macOS).
191191
* Run `python3 --version`; check that this succeeds.
192192
* Run `ninja --version`; check that this succeeds.
193193
* If you installed and want to use Sccache: Run `sccache --version`; check

include/swift/AST/AccessScope.h

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,40 @@
2020

2121
namespace swift {
2222

23+
/// Used to provide the kind of scope limitation in AccessScope::Value
24+
enum class AccessLimitKind : uint8_t { None = 0, Private, Package };
25+
2326
/// The wrapper around the outermost DeclContext from which
2427
/// a particular declaration can be accessed.
2528
class AccessScope {
26-
/// The declaration context (if not public) along with a bit saying
27-
/// whether this scope is private, SPI or not.
28-
/// If the declaration context is set, the bit means that the scope is
29-
/// private or not. If the declaration context is null, the bit means that
30-
/// this scope is SPI or not.
31-
llvm::PointerIntPair<const DeclContext *, 1, bool> Value;
29+
/// The declaration context along with an enum indicating the level of
30+
/// scope limitation.
31+
/// If the declaration context is set, and the limit kind is Private, the
32+
/// access level is considered 'private'. Whether it's 'internal' or
33+
/// 'fileprivate' is determined by what the declaration context casts to. If
34+
/// the declaration context is null, and the limit kind is None, the access
35+
/// level is considered 'public'. If the limit kind is Private, the access
36+
/// level is considered SPI. If it's Package, the access level is considered
37+
/// 'package'. Below is a table showing the combinations.
38+
///
39+
/// AccessLimitKind DC == nullptr DC != nullptr
40+
/// ---------------------------------------------------------------------------
41+
/// None public fileprivate or internal (check DC to tell which)
42+
/// Private `@_spi` public private
43+
/// Package package (unused)
44+
45+
llvm::PointerIntPair<const DeclContext *, 2, AccessLimitKind> Value;
3246

3347
public:
34-
AccessScope(const DeclContext *DC, bool isPrivate = false);
48+
AccessScope(const DeclContext *DC,
49+
AccessLimitKind limitKind = AccessLimitKind::None);
3550

36-
static AccessScope getPublic() { return AccessScope(nullptr, false); }
51+
static AccessScope getPublic() {
52+
return AccessScope(nullptr, AccessLimitKind::None);
53+
}
54+
static AccessScope getPackage() {
55+
return AccessScope(nullptr, AccessLimitKind::Package);
56+
}
3757

3858
/// Check if private access is allowed. This is a lexical scope check in Swift
3959
/// 3 mode. In Swift 4 mode, declarations and extensions of the same type will
@@ -46,25 +66,46 @@ class AccessScope {
4666
bool operator==(AccessScope RHS) const { return Value == RHS.Value; }
4767
bool operator!=(AccessScope RHS) const { return !(*this == RHS); }
4868
bool hasEqualDeclContextWith(AccessScope RHS) const {
69+
if (isPublic())
70+
return RHS.isPublic();
71+
if (isPackage())
72+
return RHS.isPackage();
4973
return getDeclContext() == RHS.getDeclContext();
5074
}
5175

52-
bool isPublic() const { return !Value.getPointer(); }
53-
bool isPrivate() const { return Value.getPointer() && Value.getInt(); }
76+
bool isPublic() const {
77+
return !Value.getPointer() && Value.getInt() == AccessLimitKind::None;
78+
}
79+
bool isPrivate() const {
80+
return Value.getPointer() && Value.getInt() == AccessLimitKind::Private;
81+
}
5482
bool isFileScope() const;
5583
bool isInternal() const;
84+
bool isPackage() const {
85+
return !Value.getPointer() && Value.getInt() == AccessLimitKind::Package;
86+
}
5687

57-
/// Returns true if this is a child scope of the specified other access scope.
58-
///
88+
/// Returns true if this scope is more restrictive than the argument scope.
89+
/// It's often used to compute the min access scope. The order of restrictiveness
90+
/// is: private (most restrictive), fileprivate, internal, package, public (least restrictive).
5991
/// \see DeclContext::isChildContextOf
6092
bool isChildOf(AccessScope AS) const {
61-
if (!isPublic() && !AS.isPublic())
62-
return allowsPrivateAccess(getDeclContext(), AS.getDeclContext());
63-
if (isPublic() && AS.isPublic())
64-
return false;
65-
return AS.isPublic();
93+
if (isInternalOrLess()) {
94+
if (AS.isInternalOrLess())
95+
return allowsPrivateAccess(getDeclContext(), AS.getDeclContext());
96+
else
97+
return AS.isPackage() || AS.isPublic();
98+
}
99+
if (isPackage())
100+
return AS.isPublic();
101+
102+
// If this is public, it can't be less than access level of AS
103+
// so return false
104+
return false;
66105
}
67106

107+
bool isInternalOrLess() const { return getDeclContext() != nullptr; }
108+
68109
/// Returns the associated access level for diagnostic purposes.
69110
AccessLevel accessLevelForDiagnostics() const;
70111

include/swift/AST/Availability.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,9 @@ class UnavailabilityReason {
224224
/// See #unionWith, #intersectWith, and #constrainWith.
225225
///
226226
/// [lattice]: http://mathworld.wolfram.com/Lattice.html
227+
///
228+
/// NOTE: Generally you should use the utilities on \c AvailabilityInference
229+
/// to create an \c AvailabilityContext, rather than creating one directly.
227230
class AvailabilityContext {
228231
VersionRange OSVersion;
229232
llvm::Optional<bool> SPI;
@@ -345,6 +348,13 @@ class AvailabilityInference {
345348
/// We assume a declaration without an annotation is always available.
346349
static AvailabilityContext availableRange(const Decl *D, ASTContext &C);
347350

351+
/// Returns the availability context for a declaration with the given
352+
/// @available attribute.
353+
///
354+
/// NOTE: The attribute must be active on the current platform.
355+
static AvailabilityContext availableRange(const AvailableAttr *attr,
356+
ASTContext &C);
357+
348358
/// Returns the attribute that should be used to determine the availability
349359
/// range of the given declaration, or nullptr if there is none.
350360
static const AvailableAttr *attrForAnnotatedAvailableRange(const Decl *D,

include/swift/AST/IRGenOptions.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,9 @@ class IRGenOptions {
422422
/// Collocate metadata functions in their own section.
423423
unsigned CollocatedMetadataFunctions : 1;
424424

425+
/// Use relative (and constant) protocol witness tables.
426+
unsigned UseRelativeProtocolWitnessTables : 1;
427+
425428
/// The number of threads for multi-threaded code generation.
426429
unsigned NumThreads = 0;
427430

@@ -493,7 +496,8 @@ class IRGenOptions {
493496
InternalizeAtLink(false), InternalizeSymbols(false),
494497
EmitGenericRODatas(false), NoPreallocatedInstantiationCaches(false),
495498
DisableReadonlyStaticObjects(false),
496-
CollocatedMetadataFunctions(false), CmdArgs(),
499+
CollocatedMetadataFunctions(false),
500+
UseRelativeProtocolWitnessTables(false), CmdArgs(),
497501
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
498502
TypeInfoFilter(TypeInfoDumpFilter::All) {
499503
#ifndef NDEBUG

include/swift/Option/FrontendOptions.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,13 @@ def disable_collocate_metadata_functions :
11191119
Flag<["-"], "disable-collocate-metadata-functions">,
11201120
HelpText<"Disable collocate metadata functions">;
11211121

1122+
def enable_relative_protocol_witness_tables :
1123+
Flag<["-"], "enable-relative-protocol-witness-tables">,
1124+
HelpText<"Enable relative protocol witness tables">;
1125+
def disable_relative_protocol_witness_tables :
1126+
Flag<["-"], "disable-relative-protocol-witness-tables">,
1127+
HelpText<"Disable relative protocol witness tables">;
1128+
11221129
def enable_new_llvm_pass_manager :
11231130
Flag<["-"], "enable-new-llvm-pass-manager">,
11241131
HelpText<"Enable the new llvm pass manager">;

include/swift/Runtime/Metadata.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,11 @@ swift_getWitnessTable(const ProtocolConformanceDescriptor *conformance,
354354
const Metadata *type,
355355
const void * const *instantiationArgs);
356356

357+
const WitnessTable *
358+
swift_getWitnessTableRelative(const ProtocolConformanceDescriptor *conformance,
359+
const Metadata *type,
360+
const void * const *instantiationArgs);
361+
357362
/// Retrieve an associated type witness from the given witness table.
358363
///
359364
/// \param wtable The witness table.
@@ -369,6 +374,13 @@ MetadataResponse swift_getAssociatedTypeWitness(
369374
const Metadata *conformingType,
370375
const ProtocolRequirement *reqBase,
371376
const ProtocolRequirement *assocType);
377+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
378+
MetadataResponse swift_getAssociatedTypeWitnessRelative(
379+
MetadataRequest request,
380+
WitnessTable *wtable,
381+
const Metadata *conformingType,
382+
const ProtocolRequirement *reqBase,
383+
const ProtocolRequirement *assocType);
372384

373385
/// Retrieve an associated conformance witness table from the given witness
374386
/// table.
@@ -388,6 +400,14 @@ const WitnessTable *swift_getAssociatedConformanceWitness(
388400
const ProtocolRequirement *reqBase,
389401
const ProtocolRequirement *assocConformance);
390402

403+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
404+
const WitnessTable *swift_getAssociatedConformanceWitnessRelative(
405+
WitnessTable *wtable,
406+
const Metadata *conformingType,
407+
const Metadata *assocType,
408+
const ProtocolRequirement *reqBase,
409+
const ProtocolRequirement *assocConformance);
410+
391411
/// Determine whether two protocol conformance descriptors describe the same
392412
/// conformance of a type to a protocol.
393413
///

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,13 @@ FUNCTION(GetWitnessTable, swift_getWitnessTable, C_CC, AlwaysAvailable,
907907
WitnessTablePtrPtrTy),
908908
ATTRS(NoUnwind, ReadOnly),
909909
EFFECT(MetaData)) // ?
910+
FUNCTION(GetWitnessTableRelative, swift_getWitnessTableRelative, C_CC, AlwaysAvailable,
911+
RETURNS(WitnessTablePtrTy),
912+
ARGS(ProtocolConformanceDescriptorPtrTy,
913+
TypeMetadataPtrTy,
914+
WitnessTablePtrPtrTy),
915+
ATTRS(NoUnwind, ReadOnly),
916+
EFFECT(MetaData)) // ?
910917

911918
// MetadataResponse swift_getAssociatedTypeWitness(
912919
// MetadataRequest request,
@@ -924,6 +931,16 @@ FUNCTION(GetAssociatedTypeWitness, swift_getAssociatedTypeWitness,
924931
ProtocolRequirementStructTy->getPointerTo()),
925932
ATTRS(NoUnwind, ReadNone, WillReturn),
926933
EFFECT(MetaData)) // ?
934+
FUNCTION(GetAssociatedTypeWitnessRelative, swift_getAssociatedTypeWitnessRelative,
935+
SwiftCC, AlwaysAvailable,
936+
RETURNS(TypeMetadataResponseTy),
937+
ARGS(SizeTy,
938+
WitnessTablePtrTy,
939+
TypeMetadataPtrTy,
940+
ProtocolRequirementStructTy->getPointerTo(),
941+
ProtocolRequirementStructTy->getPointerTo()),
942+
ATTRS(NoUnwind, ReadNone, WillReturn),
943+
EFFECT(MetaData)) // ?
927944

928945
// SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
929946
// const WitnessTable *swift_getAssociatedConformanceWitness(
@@ -942,6 +959,16 @@ FUNCTION(GetAssociatedConformanceWitness,
942959
ProtocolRequirementStructTy->getPointerTo()),
943960
ATTRS(NoUnwind, ReadNone, WillReturn),
944961
EFFECT(MetaData)) // ?
962+
FUNCTION(GetAssociatedConformanceWitnessRelative,
963+
swift_getAssociatedConformanceWitnessRelative, SwiftCC, AlwaysAvailable,
964+
RETURNS(WitnessTablePtrTy),
965+
ARGS(WitnessTablePtrTy,
966+
TypeMetadataPtrTy,
967+
TypeMetadataPtrTy,
968+
ProtocolRequirementStructTy->getPointerTo(),
969+
ProtocolRequirementStructTy->getPointerTo()),
970+
ATTRS(NoUnwind, ReadNone, WillReturn),
971+
EFFECT(MetaData)) // ?
945972

946973
// SWIFT_RUNTIME_EXPORT
947974
// SWIFT_CC(swift) bool swift_compareProtocolConformanceDescriptors(

lib/AST/Availability.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,7 @@ AvailabilityInference::annotatedAvailableRange(const Decl *D, ASTContext &Ctx) {
229229
if (!bestAvailAttr)
230230
return None;
231231

232-
return AvailabilityContext{
233-
VersionRange::allGTE(bestAvailAttr->Introduced.value()),
234-
bestAvailAttr->IsSPI};
232+
return availableRange(bestAvailAttr, Ctx);
235233
}
236234

237235
bool Decl::isAvailableAsSPI() const {
@@ -283,11 +281,8 @@ AvailabilityInference::annotatedAvailableRangeForAttr(const SpecializeAttr* attr
283281
bestAvailAttr = availAttr;
284282
}
285283

286-
if (bestAvailAttr) {
287-
return AvailabilityContext{
288-
VersionRange::allGTE(bestAvailAttr->Introduced.value())
289-
};
290-
}
284+
if (bestAvailAttr)
285+
return availableRange(bestAvailAttr, ctx);
291286

292287
return AvailabilityContext::alwaysAvailable();
293288
}
@@ -320,6 +315,14 @@ AvailabilityContext AvailabilityInference::availableRange(const Decl *D,
320315
return AvailabilityContext::alwaysAvailable();
321316
}
322317

318+
AvailabilityContext
319+
AvailabilityInference::availableRange(const AvailableAttr *attr,
320+
ASTContext &Ctx) {
321+
assert(attr->isActivePlatform(Ctx));
322+
return AvailabilityContext{VersionRange::allGTE(attr->Introduced.value()),
323+
attr->IsSPI};
324+
}
325+
323326
namespace {
324327
/// Infers the availability required to access a type.
325328
class AvailabilityInferenceTypeWalker : public TypeWalker {

lib/AST/Decl.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3732,11 +3732,13 @@ getAccessScopeForFormalAccess(const ValueDecl *VD,
37323732
while (!resultDC->isModuleScopeContext()) {
37333733
if (isa<TopLevelCodeDecl>(resultDC)) {
37343734
return AccessScope(resultDC->getModuleScopeContext(),
3735-
access == AccessLevel::Private);
3735+
access == AccessLevel::Private
3736+
? AccessLimitKind::Private
3737+
: AccessLimitKind::None);
37363738
}
37373739

37383740
if (resultDC->isLocalContext() || access == AccessLevel::Private)
3739-
return AccessScope(resultDC, /*private*/true);
3741+
return AccessScope(resultDC, AccessLimitKind::Private);
37403742

37413743
if (auto enclosingNominal = dyn_cast<GenericTypeDecl>(resultDC)) {
37423744
auto enclosingAccess =
@@ -3767,7 +3769,9 @@ getAccessScopeForFormalAccess(const ValueDecl *VD,
37673769
case AccessLevel::Private:
37683770
case AccessLevel::FilePrivate:
37693771
assert(resultDC->isModuleScopeContext());
3770-
return AccessScope(resultDC, access == AccessLevel::Private);
3772+
return AccessScope(resultDC, access == AccessLevel::Private
3773+
? AccessLimitKind::Private
3774+
: AccessLimitKind::None);
37713775
case AccessLevel::Internal:
37723776
return AccessScope(resultDC->getParentModule());
37733777
case AccessLevel::Public:

lib/AST/DeclContext.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,11 +1180,13 @@ getPrivateDeclContext(const DeclContext *DC, const SourceFile *useSF) {
11801180
return lastExtension ? lastExtension : DC;
11811181
}
11821182

1183-
AccessScope::AccessScope(const DeclContext *DC, bool isPrivate)
1184-
: Value(DC, isPrivate) {
1185-
if (isPrivate) {
1183+
AccessScope::AccessScope(const DeclContext *DC, AccessLimitKind limitKind)
1184+
: Value(DC, limitKind) {
1185+
auto isPrivate = false;
1186+
if (limitKind == AccessLimitKind::Private) {
11861187
DC = getPrivateDeclContext(DC, DC->getParentSourceFile());
11871188
Value.setPointer(DC);
1189+
isPrivate = true;
11881190
}
11891191
if (!DC || isa<ModuleDecl>(DC))
11901192
assert(!isPrivate && "public or internal scope can't be private");

lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,6 +2482,10 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
24822482
Args.hasFlag(OPT_enable_collocate_metadata_functions,
24832483
OPT_disable_collocate_metadata_functions,
24842484
Opts.CollocatedMetadataFunctions);
2485+
Opts.UseRelativeProtocolWitnessTables =
2486+
Args.hasFlag(OPT_enable_relative_protocol_witness_tables,
2487+
OPT_disable_relative_protocol_witness_tables,
2488+
Opts.UseRelativeProtocolWitnessTables);
24852489
return false;
24862490
}
24872491

lib/IRGen/GenOpaque.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,20 @@ llvm::PointerType *IRGenModule::getEnumValueWitnessTablePtrTy() {
308308

309309
Address irgen::slotForLoadOfOpaqueWitness(IRGenFunction &IGF,
310310
llvm::Value *table,
311-
WitnessIndex index) {
311+
WitnessIndex index,
312+
bool areEntriesRelative) {
312313
assert(table->getType() == IGF.IGM.WitnessTablePtrTy);
313314

315+
// Are we loading from a relative protocol witness table.
316+
if (areEntriesRelative) {
317+
llvm::Value *slot =
318+
IGF.Builder.CreateBitOrPointerCast(table, IGF.IGM.RelativeAddressPtrTy);
319+
if (index.getValue() != 0)
320+
slot = IGF.Builder.CreateConstInBoundsGEP1_32(IGF.IGM.RelativeAddressTy,
321+
slot, index.getValue());
322+
return Address(slot, IGF.IGM.RelativeAddressTy, Alignment(4));
323+
}
324+
314325
// GEP to the appropriate index, avoiding spurious IR in the trivial case.
315326
llvm::Value *slot = table;
316327
if (index.getValue() != 0)
@@ -326,8 +337,12 @@ llvm::Value *irgen::emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF,
326337
llvm::Value *table,
327338
WitnessIndex index,
328339
llvm::Value **slotPtr) {
329-
auto slot = slotForLoadOfOpaqueWitness(IGF, table, index);
340+
auto isRelativeTable = IGF.IGM.IRGen.Opts.UseRelativeProtocolWitnessTables;
341+
auto slot = slotForLoadOfOpaqueWitness(IGF, table, index, isRelativeTable);
330342
if (slotPtr) *slotPtr = slot.getAddress();
343+
if (isRelativeTable) {
344+
return IGF.emitLoadOfRelativePointer(slot, false, IGF.IGM.Int8Ty);
345+
}
331346
return IGF.emitInvariantLoad(slot);
332347
}
333348

0 commit comments

Comments
 (0)