Skip to content

Commit a8e2e01

Browse files
authored
Merge pull request #4220 from swiftwasm/main
[pull] swiftwasm from main
2 parents 36ebf9b + fe74a7d commit a8e2e01

File tree

104 files changed

+4190
-334
lines changed

Some content is hidden

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

104 files changed

+4190
-334
lines changed

include/swift/ABI/Metadata.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,7 +2462,8 @@ struct TargetGenericWitnessTable {
24622462
using PrivateDataType = void *[swift::NumGenericMetadataPrivateDataWords];
24632463

24642464
/// Private data for the instantiator. Out-of-line so that the rest
2465-
/// of this structure can be constant.
2465+
/// of this structure can be constant. Might be null when building with
2466+
/// -disable-preallocated-instantiation-caches.
24662467
RelativeDirectPointer<PrivateDataType> PrivateData;
24672468

24682469
uint16_t getWitnessTablePrivateSizeInWords() const {
@@ -3536,7 +3537,8 @@ using OpaqueTypeDescriptor = TargetOpaqueTypeDescriptor<InProcess>;
35363537
template <typename Runtime>
35373538
struct TargetGenericMetadataInstantiationCache {
35383539
/// Data that the runtime can use for its own purposes. It is guaranteed
3539-
/// to be zero-filled by the compiler.
3540+
/// to be zero-filled by the compiler. Might be null when building with
3541+
/// -disable-preallocated-instantiation-caches.
35403542
TargetPointer<Runtime, void>
35413543
PrivateData[swift::NumGenericMetadataPrivateDataWords];
35423544
};

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5240,6 +5240,10 @@ class VarDecl : public AbstractStorageDecl {
52405240
/// Is this an "async let" property?
52415241
bool isAsyncLet() const;
52425242

5243+
/// Is this a stored property that will _not_ trigger any user-defined code
5244+
/// upon any kind of access?
5245+
bool isOrdinaryStoredProperty() const;
5246+
52435247
Introducer getIntroducer() const {
52445248
return Introducer(Bits.VarDecl.Introducer);
52455249
}

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4573,6 +4573,9 @@ ERROR(distributed_actor_remote_func_implemented_manually,none,
45734573
ERROR(nonisolated_distributed_actor_storage,none,
45744574
"'nonisolated' can not be applied to distributed actor stored properties",
45754575
())
4576+
ERROR(nonisolated_storage_value_type,none,
4577+
"'nonisolated' is redundant on %0's stored properties",
4578+
(DescriptiveDeclKind))
45764579
ERROR(distributed_actor_func_nonisolated, none,
45774580
"cannot declare method %0 as both 'nonisolated' and 'distributed'",
45784581
(DeclName))
@@ -4773,6 +4776,9 @@ ERROR(global_actor_on_actor_class,none,
47734776
"actor %0 cannot have a global actor", (Identifier))
47744777
ERROR(global_actor_on_local_variable,none,
47754778
"local variable %0 cannot have a global actor", (DeclName))
4779+
ERROR(global_actor_on_storage_of_value_type,none,
4780+
"stored property %0 within %1 cannot have a global actor",
4781+
(DeclName, DescriptiveDeclKind))
47764782
ERROR(global_actor_non_unsafe_init,none,
47774783
"global actor attribute %0 argument can only be '(unsafe)'", (Type))
47784784
ERROR(global_actor_non_final_class,none,

include/swift/Basic/LangOptions.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,8 @@ namespace swift {
328328
/// Enable experimental flow-sensitive concurrent captures.
329329
bool EnableExperimentalFlowSensitiveConcurrentCaptures = false;
330330

331-
/// Enable experimental ClangImporter diagnostics.
332-
bool EnableExperimentalClangImporterDiagnostics = false;
331+
/// Disable experimental ClangImporter diagnostics.
332+
bool DisableExperimentalClangImporterDiagnostics = false;
333333

334334
/// Enable experimental eager Clang module diagnostics.
335335
bool EnableExperimentalEagerClangModuleDiagnostics = false;

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,9 @@ def enable_experimental_flow_sensitive_concurrent_captures :
287287
Flag<["-"], "enable-experimental-flow-sensitive-concurrent-captures">,
288288
HelpText<"Enable flow-sensitive concurrent captures">;
289289

290-
def enable_experimental_clang_importer_diagnostics :
291-
Flag<["-"], "enable-experimental-clang-importer-diagnostics">,
292-
HelpText<"Enable experimental diagnostics when importing C, C++, and Objective-C libraries">;
290+
def disable_experimental_clang_importer_diagnostics :
291+
Flag<["-"], "disable-experimental-clang-importer-diagnostics">,
292+
HelpText<"Disable experimental diagnostics when importing C, C++, and Objective-C libraries">;
293293

294294
def enable_experimental_eager_clang_module_diagnostics :
295295
Flag<["-"], "enable-experimental-eager-clang-module-diagnostics">,

include/swift/Reflection/ReflectionContext.h

Lines changed: 219 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ class ReflectionContext
101101
std::vector<MemoryReader::ReadBytesResult> savedBuffers;
102102
std::vector<std::tuple<RemoteAddress, RemoteAddress>> imageRanges;
103103

104+
bool setupTargetPointers = false;
105+
typename super::StoredPointer target_non_future_adapter = 0;
106+
typename super::StoredPointer target_future_adapter = 0;
107+
typename super::StoredPointer target_task_wait_throwing_resume_adapter = 0;
108+
typename super::StoredPointer target_task_future_wait_resume_adapter = 0;
109+
104110
public:
105111
using super::getBuilder;
106112
using super::readDemanglingForContextDescriptor;
@@ -137,6 +143,21 @@ class ReflectionContext
137143
std::vector<AsyncTaskAllocationChunk> Chunks;
138144
};
139145

146+
struct AsyncTaskInfo {
147+
uint32_t JobFlags;
148+
uint64_t TaskStatusFlags;
149+
uint64_t Id;
150+
StoredPointer RunJob;
151+
StoredPointer AllocatorSlabPtr;
152+
std::vector<StoredPointer> ChildTasks;
153+
std::vector<StoredPointer> AsyncBacktraceFrames;
154+
};
155+
156+
struct ActorInfo {
157+
StoredSize Flags;
158+
StoredPointer FirstJob;
159+
};
160+
140161
explicit ReflectionContext(std::shared_ptr<MemoryReader> reader)
141162
: super(std::move(reader), *this)
142163
{}
@@ -1083,6 +1104,31 @@ class ReflectionContext
10831104
return dyn_cast_or_null<const RecordTypeInfo>(TypeInfo);
10841105
}
10851106

1107+
bool metadataIsActor(StoredPointer MetadataAddress) {
1108+
auto Metadata = readMetadata(MetadataAddress);
1109+
if (!Metadata)
1110+
return false;
1111+
1112+
// Only classes can be actors.
1113+
if (Metadata->getKind() != MetadataKind::Class)
1114+
return false;
1115+
1116+
auto DescriptorAddress =
1117+
super::readAddressOfNominalTypeDescriptor(Metadata);
1118+
if (!DescriptorAddress)
1119+
return false;
1120+
1121+
auto DescriptorBytes =
1122+
getReader().readBytes(RemoteAddress(DescriptorAddress),
1123+
sizeof(TargetTypeContextDescriptor<Runtime>));
1124+
if (!DescriptorBytes)
1125+
return false;
1126+
auto Descriptor =
1127+
reinterpret_cast<const TargetTypeContextDescriptor<Runtime> *>(
1128+
DescriptorBytes.get());
1129+
return Descriptor->getTypeContextDescriptorFlags().class_isActor();
1130+
}
1131+
10861132
/// Iterate the protocol conformance cache tree rooted at NodePtr, calling
10871133
/// Call with the type and protocol in each node.
10881134
void iterateConformanceTree(StoredPointer NodePtr,
@@ -1394,22 +1440,179 @@ class ReflectionContext
13941440
return {llvm::None, {Slab->Next, SlabSize, {Chunk}}};
13951441
}
13961442

1397-
std::pair<llvm::Optional<std::string>, StoredPointer>
1398-
asyncTaskSlabPtr(StoredPointer AsyncTaskPtr) {
1399-
using AsyncTask = AsyncTask<Runtime>;
1400-
1401-
auto AsyncTaskBytes =
1402-
getReader().readBytes(RemoteAddress(AsyncTaskPtr), sizeof(AsyncTask));
1403-
auto *AsyncTaskObj =
1404-
reinterpret_cast<const AsyncTask *>(AsyncTaskBytes.get());
1443+
std::pair<llvm::Optional<std::string>, AsyncTaskInfo>
1444+
asyncTaskInfo(StoredPointer AsyncTaskPtr) {
1445+
auto AsyncTaskObj = readObj<AsyncTask<Runtime>>(AsyncTaskPtr);
14051446
if (!AsyncTaskObj)
1406-
return {std::string("failure reading async task"), 0};
1447+
return {std::string("failure reading async task"), {}};
1448+
1449+
AsyncTaskInfo Info{};
1450+
Info.JobFlags = AsyncTaskObj->Flags;
1451+
Info.TaskStatusFlags = AsyncTaskObj->PrivateStorage.Status.Flags;
1452+
Info.Id =
1453+
AsyncTaskObj->Id | ((uint64_t)AsyncTaskObj->PrivateStorage.Id << 32);
1454+
Info.AllocatorSlabPtr = AsyncTaskObj->PrivateStorage.Allocator.FirstSlab;
1455+
Info.RunJob = getRunJob(AsyncTaskObj.get());
1456+
1457+
// Find all child tasks.
1458+
auto RecordPtr = AsyncTaskObj->PrivateStorage.Status.Record;
1459+
while (RecordPtr) {
1460+
auto RecordObj = readObj<TaskStatusRecord<Runtime>>(RecordPtr);
1461+
if (!RecordObj)
1462+
break;
1463+
1464+
// This cuts off high bits if our size_t doesn't match the target's. We
1465+
// only read the Kind bits which are at the bottom, so that's OK here.
1466+
// Beware of this when reading anything else.
1467+
TaskStatusRecordFlags Flags{RecordObj->Flags};
1468+
auto Kind = Flags.getKind();
1469+
1470+
StoredPointer ChildTask = 0;
1471+
if (Kind == TaskStatusRecordKind::ChildTask) {
1472+
auto RecordObj = readObj<ChildTaskStatusRecord<Runtime>>(RecordPtr);
1473+
if (RecordObj)
1474+
ChildTask = RecordObj->FirstChild;
1475+
} else if (Kind == TaskStatusRecordKind::TaskGroup) {
1476+
auto RecordObj = readObj<TaskGroupTaskStatusRecord<Runtime>>(RecordPtr);
1477+
if (RecordObj)
1478+
ChildTask = RecordObj->FirstChild;
1479+
}
1480+
1481+
while (ChildTask) {
1482+
Info.ChildTasks.push_back(ChildTask);
1483+
1484+
StoredPointer ChildFragmentAddr =
1485+
ChildTask + sizeof(AsyncTask<Runtime>);
1486+
auto ChildFragmentObj =
1487+
readObj<ChildFragment<Runtime>>(ChildFragmentAddr);
1488+
if (ChildFragmentObj)
1489+
ChildTask = ChildFragmentObj->NextChild;
1490+
else
1491+
ChildTask = 0;
1492+
}
1493+
1494+
RecordPtr = RecordObj->Parent;
1495+
}
1496+
1497+
// Walk the async backtrace if the task isn't running or cancelled.
1498+
// TODO: Use isEnqueued from https://github.com/apple/swift/pull/41088/ once
1499+
// that's available.
1500+
int IsCancelledFlag = 0x100;
1501+
int IsRunningFlag = 0x800;
1502+
if (!(AsyncTaskObj->PrivateStorage.Status.Flags & IsCancelledFlag) &&
1503+
!(AsyncTaskObj->PrivateStorage.Status.Flags & IsRunningFlag)) {
1504+
auto ResumeContext = AsyncTaskObj->ResumeContextAndReserved[0];
1505+
while (ResumeContext) {
1506+
auto ResumeContextObj = readObj<AsyncContext<Runtime>>(ResumeContext);
1507+
if (!ResumeContextObj)
1508+
break;
1509+
Info.AsyncBacktraceFrames.push_back(
1510+
stripSignedPointer(ResumeContextObj->ResumeParent));
1511+
ResumeContext = stripSignedPointer(ResumeContextObj->Parent);
1512+
}
1513+
}
1514+
1515+
return {llvm::None, Info};
1516+
}
1517+
1518+
std::pair<llvm::Optional<std::string>, ActorInfo>
1519+
actorInfo(StoredPointer ActorPtr) {
1520+
using DefaultActorImpl = DefaultActorImpl<Runtime>;
1521+
1522+
auto ActorObj = readObj<DefaultActorImpl>(ActorPtr);
1523+
if (!ActorObj)
1524+
return {std::string("failure reading actor"), {}};
1525+
1526+
ActorInfo Info{};
1527+
Info.Flags = ActorObj->Flags;
1528+
1529+
// Status is the low 3 bits of Flags. Status of 0 is Idle. Don't read
1530+
// FirstJob when idle.
1531+
auto Status = Info.Flags & 0x7;
1532+
if (Status != 0) {
1533+
// This is a JobRef which stores flags in the low bits.
1534+
Info.FirstJob = ActorObj->FirstJob & ~StoredPointer(0x3);
1535+
}
1536+
return {llvm::None, Info};
1537+
}
14071538

1408-
StoredPointer SlabPtr = AsyncTaskObj->PrivateStorage.Allocator.FirstSlab;
1409-
return {llvm::None, SlabPtr};
1539+
StoredPointer nextJob(StoredPointer JobPtr) {
1540+
using Job = Job<Runtime>;
1541+
1542+
auto JobBytes = getReader().readBytes(RemoteAddress(JobPtr), sizeof(Job));
1543+
auto *JobObj = reinterpret_cast<const Job *>(JobBytes.get());
1544+
if (!JobObj)
1545+
return 0;
1546+
1547+
// This is a JobRef which stores flags in the low bits.
1548+
return JobObj->SchedulerPrivate[0] & ~StoredPointer(0x3);
14101549
}
14111550

14121551
private:
1552+
// Get the most human meaningful "run job" function pointer from the task,
1553+
// like AsyncTask::getResumeFunctionForLogging does.
1554+
StoredPointer getRunJob(const AsyncTask<Runtime> *AsyncTaskObj) {
1555+
auto Fptr = stripSignedPointer(AsyncTaskObj->RunJob);
1556+
1557+
loadTargetPointers();
1558+
auto ResumeContextPtr = AsyncTaskObj->ResumeContextAndReserved[0];
1559+
if (target_non_future_adapter && Fptr == target_non_future_adapter) {
1560+
using Prefix = AsyncContextPrefix<Runtime>;
1561+
auto PrefixAddr = ResumeContextPtr - sizeof(Prefix);
1562+
auto PrefixBytes =
1563+
getReader().readBytes(RemoteAddress(PrefixAddr), sizeof(Prefix));
1564+
if (PrefixBytes) {
1565+
auto PrefixPtr = reinterpret_cast<const Prefix *>(PrefixBytes.get());
1566+
return stripSignedPointer(PrefixPtr->AsyncEntryPoint);
1567+
}
1568+
} else if (target_future_adapter && Fptr == target_future_adapter) {
1569+
using Prefix = FutureAsyncContextPrefix<Runtime>;
1570+
auto PrefixAddr = ResumeContextPtr - sizeof(Prefix);
1571+
auto PrefixBytes =
1572+
getReader().readBytes(RemoteAddress(PrefixAddr), sizeof(Prefix));
1573+
if (PrefixBytes) {
1574+
auto PrefixPtr = reinterpret_cast<const Prefix *>(PrefixBytes.get());
1575+
return stripSignedPointer(PrefixPtr->AsyncEntryPoint);
1576+
}
1577+
} else if ((target_task_wait_throwing_resume_adapter &&
1578+
Fptr == target_task_wait_throwing_resume_adapter) ||
1579+
(target_task_future_wait_resume_adapter &&
1580+
Fptr == target_task_future_wait_resume_adapter)) {
1581+
auto ContextBytes = getReader().readBytes(RemoteAddress(ResumeContextPtr),
1582+
sizeof(AsyncContext<Runtime>));
1583+
if (ContextBytes) {
1584+
auto ContextPtr =
1585+
reinterpret_cast<const AsyncContext<Runtime> *>(ContextBytes.get());
1586+
return stripSignedPointer(ContextPtr->ResumeParent);
1587+
}
1588+
}
1589+
1590+
return Fptr;
1591+
}
1592+
1593+
void loadTargetPointers() {
1594+
if (setupTargetPointers)
1595+
return;
1596+
1597+
auto getFunc = [&](const std::string &name) -> StoredPointer {
1598+
auto Symbol = getReader().getSymbolAddress(name);
1599+
if (!Symbol)
1600+
return 0;
1601+
auto Pointer = getReader().readPointer(Symbol, sizeof(StoredPointer));
1602+
if (!Pointer)
1603+
return 0;
1604+
return Pointer->getResolvedAddress().getAddressData();
1605+
};
1606+
target_non_future_adapter =
1607+
getFunc("_swift_concurrency_debug_non_future_adapter");
1608+
target_future_adapter = getFunc("_swift_concurrency_debug_future_adapter");
1609+
target_task_wait_throwing_resume_adapter =
1610+
getFunc("_swift_concurrency_debug_task_wait_throwing_resume_adapter");
1611+
target_task_future_wait_resume_adapter =
1612+
getFunc("_swift_concurrency_debug_task_future_wait_resume_adapter");
1613+
setupTargetPointers = true;
1614+
}
1615+
14131616
const TypeInfo *
14141617
getClosureContextInfo(StoredPointer Context, const ClosureContextInfo &Info,
14151618
remote::TypeInfoProvider *ExternalTypeInfo) {
@@ -1631,6 +1834,11 @@ class ReflectionContext
16311834

16321835
return llvm::None;
16331836
}
1837+
1838+
template <typename T>
1839+
MemoryReader::ReadObjResult<T> readObj(StoredPointer Ptr) {
1840+
return getReader().template readObj<T>(RemoteAddress(Ptr));
1841+
}
16341842
};
16351843

16361844
} // end namespace reflection

0 commit comments

Comments
 (0)