@@ -577,10 +577,15 @@ IRGenModule::IRGenModule(IRGenerator &irgen,
577577 AtomicBoolSize = Size (ClangASTContext->getTypeSize (atomicBoolTy));
578578 AtomicBoolAlign = Alignment (ClangASTContext->getTypeSize (atomicBoolTy));
579579 }
580-
581- IsSwiftErrorInRegister =
580+ // On WebAssembly, tail optional arguments are not allowed because Wasm requires
581+ // callee and caller signature to be the same. So LLVM adds dummy arguments for
582+ // `swiftself` and `swifterror`. If there is `swiftself` but is no `swifterror` in
583+ // a swiftcc function or invocation, then LLVM adds dummy `swifterror` parameter or
584+ // argument. To count up how many dummy arguments should be added, we need to mark
585+ // it as `swifterror` even though it's not in register.
586+ ShouldUseSwiftError =
582587 clang::CodeGen::swiftcall::isSwiftErrorLoweredInRegister (
583- ClangCodeGen->CGM ());
588+ ClangCodeGen->CGM ()) || TargetInfo. OutputObjectFormat == llvm::Triple::Wasm ;
584589
585590#ifndef NDEBUG
586591 sanityCheckStdlib (*this );
@@ -881,7 +886,8 @@ llvm::Constant *swift::getRuntimeFn(llvm::Module &Module,
881886 RuntimeAvailability availability,
882887 llvm::ArrayRef<llvm::Type*> retTypes,
883888 llvm::ArrayRef<llvm::Type*> argTypes,
884- ArrayRef<Attribute::AttrKind> attrs) {
889+ ArrayRef<Attribute::AttrKind> attrs,
890+ IRGenModule *IGM) {
885891
886892 if (cache)
887893 return cache;
@@ -954,6 +960,22 @@ llvm::Constant *swift::getRuntimeFn(llvm::Module &Module,
954960 fn->addFnAttrs (buildFnAttr);
955961 fn->addRetAttrs (buildRetAttr);
956962 fn->addParamAttrs (0 , buildFirstParamAttr);
963+
964+ // Add swiftself and swifterror attributes only when swift_willThrow
965+ // swift_willThrow is defined in RuntimeFunctions.def, but due to the
966+ // DSL limitation, arguments attributes are not set.
967+ // On the other hand, caller of `swift_willThrow` assumes that it's attributed
968+ // with `swiftself` and `swifterror`.
969+ // This mismatch of attributes would be issue when lowering to WebAssembly.
970+ // While lowering, LLVM counts how many dummy params are necessary to match
971+ // callee and caller signature. So we need to add them correctly.
972+ if (functionName == " swift_willThrow" ) {
973+ assert (IGM && " IGM is required for swift_willThrow." );
974+ fn->addParamAttr (0 , Attribute::AttrKind::SwiftSelf);
975+ if (IGM->ShouldUseSwiftError ) {
976+ fn->addParamAttr (1 , Attribute::AttrKind::SwiftError);
977+ }
978+ }
957979 }
958980
959981 return cache;
@@ -997,7 +1019,7 @@ void IRGenModule::registerRuntimeEffect(ArrayRef<RuntimeEffect> effect,
9971019 registerRuntimeEffect (EFFECT, #NAME); \
9981020 return getRuntimeFn (Module, ID##Fn, #NAME, CC, \
9991021 AVAILABILITY (this ->Context ), \
1000- RETURNS, ARGS, ATTRS); \
1022+ RETURNS, ARGS, ATTRS, this ); \
10011023 }
10021024
10031025#include " swift/Runtime/RuntimeFunctions.def"
0 commit comments