From 89627a91e1c3fed04037344c3a729d01cac4fc88 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Fri, 25 Dec 2020 00:25:43 +0900 Subject: [PATCH 1/7] Avoid illegal function pointer operation for async funcs If function pointer is a direct pointer to a function, it could not be an async function pointer. And additive operation to function address is illegal on some archs like wasm32, so emit undefs instead. --- lib/IRGen/GenCall.cpp | 53 +++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index ac2b952d5e0ec..253f8147626f7 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -1956,27 +1956,42 @@ std::pair irgen::getAsyncFunctionAndSize( { // thin IGF.Builder.emitBlock(thinBlock); auto *ptr = functionPointer.getRawPointer(); - if (auto authInfo = functionPointer.getAuthInfo()) { - ptr = emitPointerAuthAuth(IGF, ptr, authInfo); - } - auto *afpPtr = - IGF.Builder.CreateBitCast(ptr, IGF.IGM.AsyncFunctionPointerPtrTy); - if (emitFunction) { - llvm::Value *addrPtr = IGF.Builder.CreateStructGEP(afpPtr, 0); - auto *uncastFnPtr = IGF.emitLoadOfRelativePointer( - Address(addrPtr, IGF.IGM.getPointerAlignment()), /*isFar*/ false, - /*expectedType*/ functionPointer.getFunctionType()->getPointerTo()); - auto *fnPtr = IGF.Builder.CreateBitCast(uncastFnPtr, IGF.IGM.Int8PtrTy); + + // If function pointer is a direct pointer to a function, it could not be + // an async function pointer. And additive operation to function address is + // illegal on some archs like wasm32, so emit undefs instead. + if (isa(ptr)) { + if (emitFunction) { + auto *undef = llvm::UndefValue::get(IGF.IGM.Int8PtrTy); + fnPhiValues.push_back({thinBlock, undef}); + } + if (emitSize) { + auto *undef = llvm::UndefValue::get(IGF.IGM.Int32Ty); + sizePhiValues.push_back({thinBlock, undef}); + } + } else { if (auto authInfo = functionPointer.getAuthInfo()) { - fnPtr = emitPointerAuthSign(IGF, fnPtr, authInfo); + ptr = emitPointerAuthAuth(IGF, ptr, authInfo); + } + auto *afpPtr = + IGF.Builder.CreateBitCast(ptr, IGF.IGM.AsyncFunctionPointerPtrTy); + if (emitFunction) { + llvm::Value *addrPtr = IGF.Builder.CreateStructGEP(afpPtr, 0); + auto *uncastFnPtr = IGF.emitLoadOfRelativePointer( + Address(addrPtr, IGF.IGM.getPointerAlignment()), /*isFar*/ false, + /*expectedType*/ functionPointer.getFunctionType()->getPointerTo()); + auto *fnPtr = IGF.Builder.CreateBitCast(uncastFnPtr, IGF.IGM.Int8PtrTy); + if (auto authInfo = functionPointer.getAuthInfo()) { + fnPtr = emitPointerAuthSign(IGF, fnPtr, authInfo); + } + fnPhiValues.push_back({thinBlock, fnPtr}); + } + if (emitSize) { + auto *sizePtr = IGF.Builder.CreateStructGEP(afpPtr, 1); + auto *size = + IGF.Builder.CreateLoad(sizePtr, IGF.IGM.getPointerAlignment()); + sizePhiValues.push_back({thinBlock, size}); } - fnPhiValues.push_back({thinBlock, fnPtr}); - } - if (emitSize) { - auto *sizePtr = IGF.Builder.CreateStructGEP(afpPtr, 1); - auto *size = - IGF.Builder.CreateLoad(sizePtr, IGF.IGM.getPointerAlignment()); - sizePhiValues.push_back({thinBlock, size}); } IGF.Builder.CreateBr(joinBlock); } From 2b7d31b70c8001d3c7b429ca84c1146c33ef5e50 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Fri, 1 Jan 2021 13:24:24 +0900 Subject: [PATCH 2/7] Guard unused libdispatch header --- stdlib/public/Concurrency/GlobalExecutor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stdlib/public/Concurrency/GlobalExecutor.cpp b/stdlib/public/Concurrency/GlobalExecutor.cpp index 4eb46c7f41139..2a68077b2a834 100644 --- a/stdlib/public/Concurrency/GlobalExecutor.cpp +++ b/stdlib/public/Concurrency/GlobalExecutor.cpp @@ -56,7 +56,9 @@ #include "swift/Runtime/Concurrency.h" #include "TaskPrivate.h" +#if !SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR #include +#endif using namespace swift; From 1f69c6ff759a1107546b8b50449cbd11c21b4606 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Fri, 1 Jan 2021 13:27:45 +0900 Subject: [PATCH 3/7] Activate SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY --- cmake/caches/Runtime-WASI-wasm32.cmake | 2 +- utils/webassembly/build-presets.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/caches/Runtime-WASI-wasm32.cmake b/cmake/caches/Runtime-WASI-wasm32.cmake index bcb952c4f2f04..84e1b602d19e1 100644 --- a/cmake/caches/Runtime-WASI-wasm32.cmake +++ b/cmake/caches/Runtime-WASI-wasm32.cmake @@ -18,7 +18,7 @@ set(SWIFTWASM_DISABLE_REFLECTION_TEST YES CACHE BOOL "") # stdlib configurations set(SWIFT_BUILD_STATIC_STDLIB YES CACHE BOOL "") set(SWIFT_BUILD_DYNAMIC_STDLIB NO CACHE BOOL "") -set(SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY NO CACHE BOOL "") +set(SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY YES CACHE BOOL "") # TODO(katei): This should get turned off, as this is not an ABI stable platform. # But current CMake build system doesn't support SWIFT_STDLIB_STABLE_ABI=NO set(SWIFT_STDLIB_STABLE_ABI YES CACHE BOOL "") diff --git a/utils/webassembly/build-presets.ini b/utils/webassembly/build-presets.ini index 9befdde5f060c..38f873c794eb5 100644 --- a/utils/webassembly/build-presets.ini +++ b/utils/webassembly/build-presets.ini @@ -9,7 +9,7 @@ skip-build-benchmarks llvm-targets-to-build=X86;AArch64;WebAssembly swift-darwin-supported-archs=%(HOST_ARCHITECTURE)s compiler-vendor=swiftwasm -enable-experimental-concurrency=0 +enable-experimental-concurrency=1 [preset: webassembly-install] From cf46e94b3d0bff9b54b95cacc446e7c9fbb5776f Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 2 Jan 2021 01:03:08 +0900 Subject: [PATCH 4/7] [WASM] Replace relative ptr use for async func ptr with absolute ptr --- lib/IRGen/IRGenFunction.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/IRGen/IRGenFunction.cpp b/lib/IRGen/IRGenFunction.cpp index a68e14f09e1fa..3fd4abcd92397 100644 --- a/lib/IRGen/IRGenFunction.cpp +++ b/lib/IRGen/IRGenFunction.cpp @@ -318,6 +318,14 @@ IRGenFunction::emitLoadOfRelativePointer(Address addr, bool isFar, if (!isFar) { value = Builder.CreateSExt(value, IGM.IntPtrTy); } + + // FIXME: add absolute pointer mode for IRGen + if (IGM.TargetInfo.OutputObjectFormat == llvm::Triple::Wasm) { + auto *uncastPointer = Builder.CreateIntToPtr(value, IGM.Int8PtrTy); + auto uncastPointerAddress = Address(uncastPointer, IGM.getPointerAlignment()); + auto pointer = Builder.CreateBitCast(uncastPointerAddress, expectedType); + return pointer.getAddress(); + } auto *addrInt = Builder.CreatePtrToInt(addr.getAddress(), IGM.IntPtrTy); auto *uncastPointerInt = Builder.CreateAdd(addrInt, value); auto *uncastPointer = Builder.CreateIntToPtr(uncastPointerInt, IGM.Int8PtrTy); From 662d7bd18daa2c9e7eac28e4c8659dea91ce5f30 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 2 Jan 2021 01:03:51 +0900 Subject: [PATCH 5/7] [WASM] Sync calling convention between C++ and Swift --- include/swift/Runtime/HeapObject.h | 1 + include/swift/Runtime/RuntimeFunctions.def | 2 +- stdlib/public/runtime/HeapObject.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/swift/Runtime/HeapObject.h b/include/swift/Runtime/HeapObject.h index 5ab9a98eb354c..df286c0e1ef5d 100644 --- a/include/swift/Runtime/HeapObject.h +++ b/include/swift/Runtime/HeapObject.h @@ -148,6 +148,7 @@ void swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask); /// It may also prove worthwhile to have this use a custom CC /// which preserves a larger set of registers. SWIFT_RUNTIME_EXPORT +SWIFT_CC(swift) HeapObject *swift_retain(HeapObject *object); SWIFT_RUNTIME_EXPORT diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def index 47abdc8afc02d..3b9de721fd49b 100644 --- a/include/swift/Runtime/RuntimeFunctions.def +++ b/include/swift/Runtime/RuntimeFunctions.def @@ -155,7 +155,7 @@ FUNCTION(CopyPOD, swift_copyPOD, C_CC, AlwaysAvailable, ATTRS(NoUnwind)) // void *swift_retain(void *ptr); -FUNCTION(NativeStrongRetain, swift_retain, C_CC, AlwaysAvailable, +FUNCTION(NativeStrongRetain, swift_retain, SwiftCC, AlwaysAvailable, RETURNS(RefCountedPtrTy), ARGS(RefCountedPtrTy), ATTRS(NoUnwind, FirstParamReturned)) diff --git a/stdlib/public/runtime/HeapObject.cpp b/stdlib/public/runtime/HeapObject.cpp index fcac5d8545566..05b0da92a2f81 100644 --- a/stdlib/public/runtime/HeapObject.cpp +++ b/stdlib/public/runtime/HeapObject.cpp @@ -341,6 +341,7 @@ static HeapObject *_swift_retain_(HeapObject *object) { return object; } +SWIFT_CC(swift) HeapObject *swift::swift_retain(HeapObject *object) { #ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME return swift_nonatomic_retain(object); From be3f1a9992aa6d965643d6dc41544c64ed75a2ea Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 2 Jan 2021 01:04:32 +0900 Subject: [PATCH 6/7] Define duplicated fatalError as weak symbol to avoid conflict while linking --- stdlib/public/Concurrency/Mutex.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/stdlib/public/Concurrency/Mutex.cpp b/stdlib/public/Concurrency/Mutex.cpp index 70115cc8251e6..6f59f6fae932b 100644 --- a/stdlib/public/Concurrency/Mutex.cpp +++ b/stdlib/public/Concurrency/Mutex.cpp @@ -20,6 +20,7 @@ #include "swift/Runtime/MutexSingleThreaded.h" #endif +__attribute__ ((weak)) SWIFT_NORETURN void swift::fatalError(uint32_t flags, const char *format, ...) { abort(); } From b565d02739ffce1093c4535f61de931b934cfb7b Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 2 Jan 2021 01:05:33 +0900 Subject: [PATCH 7/7] Sync swift_retain signature between Swift and C++ --- stdlib/public/Concurrency/TaskGroup.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/Concurrency/TaskGroup.swift b/stdlib/public/Concurrency/TaskGroup.swift index 8623e58833a43..bb0926cecf605 100644 --- a/stdlib/public/Concurrency/TaskGroup.swift +++ b/stdlib/public/Concurrency/TaskGroup.swift @@ -267,7 +267,7 @@ extension Task.Group { @_silgen_name("swift_retain") func _swiftRetain( _ task: Builtin.NativeObject -) +) -> UInt @_silgen_name("swift_task_group_add_pending") func _taskGroupAddPendingTask(