Skip to content

Commit a9b9a08

Browse files
committed
SILLinker: de-serialize Executor witness tables for the xExecutorRef builtins
Fixes unresolved symbol linker errors in embedded mode. rdar://148538336
1 parent ca71950 commit a9b9a08

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

lib/SIL/IR/Linker.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,24 @@ void SILLinkerVisitor::visitInitExistentialRefInst(
429429
}
430430
}
431431

432+
void SILLinkerVisitor::visitBuiltinInst(BuiltinInst *bi) {
433+
switch (bi->getBuiltinInfo().ID) {
434+
case BuiltinValueKind::BuildOrdinaryTaskExecutorRef:
435+
case BuiltinValueKind::BuildOrdinarySerialExecutorRef:
436+
case BuiltinValueKind::BuildComplexEqualitySerialExecutorRef:
437+
if (Mod.getOptions().EmbeddedSwift) {
438+
// Those builtins act like init_existential_ref instructions and therefore
439+
// it's important to have the Executor witness tables available in embedded
440+
// mode.
441+
auto executorConf = bi->getSubstitutions().getConformances()[0];
442+
visitProtocolConformance(executorConf, true);
443+
}
444+
break;
445+
default:
446+
break;
447+
}
448+
}
449+
432450
void SILLinkerVisitor::visitAllocRefDynamicInst(AllocRefDynamicInst *ARI) {
433451
if (!isLinkAll())
434452
return;

lib/SIL/IR/Linker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class SILLinkerVisitor : public SILInstructionVisitor<SILLinkerVisitor, void> {
129129
}
130130
void visitInitExistentialAddrInst(InitExistentialAddrInst *IEI);
131131
void visitInitExistentialRefInst(InitExistentialRefInst *IERI);
132+
void visitBuiltinInst(BuiltinInst *bi);
132133
void visitAllocRefInst(AllocRefInst *ARI);
133134
void visitAllocRefDynamicInst(AllocRefDynamicInst *ARI);
134135
void visitMetatypeInst(MetatypeInst *MI);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %{python} %utils/split_file.py -o %t %s
3+
4+
// RUN: %target-swift-frontend -emit-module -o %t/MyModule.swiftmodule %t/MyModule.swift -enable-experimental-feature Embedded -parse-as-library
5+
// RUN: %target-swift-frontend -c -I %t %t/Main.swift -enable-experimental-feature Embedded -o %t/a.o -parse-as-library
6+
// RUN: %target-clang %t/a.o -o %t/a.out -L%swift_obj_root/lib/swift/embedded/%target-cpu-apple-macos -lswift_Concurrency -lswift_ConcurrencyDefaultExecutor -dead_strip
7+
// RUN: %target-run %t/a.out | %FileCheck %s
8+
9+
// REQUIRES: swift_in_compiler
10+
// REQUIRES: executable_test
11+
// REQUIRES: OS=macosx || OS=linux-gnu
12+
// REQUIRES: swift_feature_Embedded
13+
14+
// BEGIN MyModule.swift
15+
16+
import _Concurrency
17+
18+
nonisolated(unsafe) var glob: UnsafeMutableRawPointer? = nil
19+
nonisolated(unsafe) var job: UnownedJob? = nil
20+
21+
public final class MyCustomExecutor: SerialExecutor, @unchecked Sendable {
22+
private init() {}
23+
24+
nonisolated(unsafe)
25+
public static var shared: MyCustomExecutor = MyCustomExecutor()
26+
27+
public static func installGlobalExecutor() {
28+
let fn: @convention(thin) () -> () = {
29+
MyCustomExecutor.shared.unsafeEnqueue(job!)
30+
}
31+
glob = unsafeBitCast(fn, to: UnsafeMutableRawPointer?.self)
32+
}
33+
34+
private func enqueue(_ job: UnownedJob, withDelay nanoseconds: UInt64) {}
35+
36+
private func unsafeEnqueue(_ job: UnownedJob) {
37+
job.runSynchronously(on: self.asUnownedSerialExecutor())
38+
}
39+
40+
public func enqueue(_ job: consuming ExecutorJob) {
41+
unsafeEnqueue(UnownedJob(job))
42+
}
43+
44+
public func asUnownedSerialExecutor() -> UnownedSerialExecutor {
45+
return UnownedSerialExecutor(ordinary: self)
46+
}
47+
}
48+
49+
// BEGIN Main.swift
50+
51+
import MyModule
52+
import _Concurrency
53+
54+
@main
55+
struct Entrypoint {
56+
static func main() async {
57+
MyCustomExecutor.installGlobalExecutor()
58+
print("OK!")
59+
}
60+
}
61+
62+
// CHECK: OK!

0 commit comments

Comments
 (0)