Skip to content

[Experimental] async/await support #2408

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmake/caches/Runtime-WASI-wasm32.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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 "")
Expand Down
1 change: 1 addition & 0 deletions include/swift/Runtime/HeapObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Runtime/RuntimeFunctions.def
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
53 changes: 34 additions & 19 deletions lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1956,27 +1956,42 @@ std::pair<llvm::Value *, llvm::Value *> 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<llvm::Function>(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);
}
Expand Down
8 changes: 8 additions & 0 deletions lib/IRGen/IRGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions stdlib/public/Concurrency/GlobalExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@
#include "swift/Runtime/Concurrency.h"
#include "TaskPrivate.h"

#if !SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
#include <dispatch/dispatch.h>
#endif

using namespace swift;

Expand Down
1 change: 1 addition & 0 deletions stdlib/public/Concurrency/Mutex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "swift/Runtime/MutexSingleThreaded.h"
#endif

__attribute__ ((weak))
SWIFT_NORETURN void swift::fatalError(uint32_t flags, const char *format, ...) {
abort();
}
2 changes: 1 addition & 1 deletion stdlib/public/Concurrency/TaskGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions stdlib/public/runtime/HeapObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion utils/webassembly/build-presets.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand Down