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/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/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); } 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); 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; 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(); } 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( 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); 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]