Files
swift-mirror/test/IRGen/async/run-call-nonresilient-classinstance-void-to-void.swift
Saleem Abdulrasool 68bc33fed3 IRGen: initial pass to support async inheritance on Windows
With PE/COFF, one cannot reference a data symbol directly across the
binary module boundary.  Instead, the reference must be indirected
through the Import Address Table (IAT) to allow for position
independence.

When generating a reference to a AsyncFunctionPointer ({i8*, i32}), we
tag the pointer as being indirected by tagging bit 1 (with the
assumption that native alignment will ensure 4/8 byte alignment, freeing
the bottom 2 bits at least for bit-packing).  We tweak the
v-table/witness table emission such that all references to the
AsyncFunctionPointer are replaced with the linker synthetic import
symbol with the bit packing:

~~~
.quad __imp_$s1L1CC1yyYaKFTu+1
~~~

rather than

~~~
.quad $s1L1CC1yyYaKFTu
~~~

Upon access of the async function pointer reference, we open-code the
check for the following:

~~~
pointer = (pointer & 1) ? *(void **)(pointer & ~1) : pointer;
~~~

Thanks to @DougGregor for the discussion and the suggestion for the
pointer tagging.  Thanks to @aschwaighofer for pointers to the code that
I had missed.  Also, thanks to @SeanROlszewski for the original code
sample that led to the reduced test case.

Fixes: SR-15399
2021-11-01 11:23:51 -07:00

33 lines
1.4 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: %target-build-swift-dylib(%t/%target-library-name(NonresilientClass)) %S/Inputs/class_open-1instance-void_to_void.swift -Xfrontend -disable-availability-checking -g -module-name NonresilientClass -emit-module -emit-module-path %t/NonresilientClass.swiftmodule
// RUN: %target-codesign %t/%target-library-name(NonresilientClass)
// RUN: %target-build-swift -Xfrontend -disable-availability-checking -g %S/Inputs/class_open-1instance-void_to_void.swift -emit-ir -I %t -L %t -lNonresilientClass -parse-as-library -module-name main | %FileCheck %S/Inputs/class_open-1instance-void_to_void.swift --check-prefix=CHECK-LL
// RUN: %target-build-swift -Xfrontend -disable-availability-checking -g %s -parse-as-library -module-name main -o %t/main -I %t -L %t -lNonresilientClass %target-rpath(%t)
// RUN: %target-codesign %t/main
// RUN: %target-run %t/main %t/%target-library-name(NonresilientClass) | %FileCheck %s
// REQUIRES: executable_test
// REQUIRES: swift_test_mode_optimize_none
// REQUIRES: concurrency
// REQUIRES: concurrency_runtime
// UNSUPPORTED: back_deployment_runtime
import _Concurrency
import NonresilientClass
class D : C {
}
// CHECK: entering call_f
// CHECK: entering f
// CHECK: D
// CHECK: main.D
// CHECK: exiting f
// CHECK: exiting call_f
@main struct Main {
static func main() async {
let c = D()
await call_f(c)
}
}