Skip to content

Commit 22ab6e3

Browse files
authored
Merge pull request #3832 from swiftwasm/release/5.5
[pull] swiftwasm-release/5.5 from release/5.5
2 parents e207375 + c39901d commit 22ab6e3

File tree

4 files changed

+163
-33
lines changed

4 files changed

+163
-33
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3270,26 +3270,33 @@ class ArgEmitter {
32703270
}
32713271

32723272
void maybeEmitForeignArgument() {
3273-
if (Foreign.async
3274-
&& Foreign.async->completionHandlerParamIndex() == Args.size()) {
3275-
SILParameterInfo param = claimNextParameters(1).front();
3276-
(void)param;
3277-
3278-
// Leave a placeholder in the position. We'll fill this in with a block
3279-
// capturing the current continuation right before we invoke the
3280-
// function.
3281-
// (We can't do this immediately, because evaluating other arguments
3282-
// may require suspending the async task, which is not allowed while its
3283-
// continuation is active.)
3284-
Args.push_back(ManagedValue::forInContext());
3285-
} else if (Foreign.error
3286-
&& Foreign.error->getErrorParameterIndex() == Args.size()) {
3287-
SILParameterInfo param = claimNextParameters(1).front();
3288-
assert(param.getConvention() == ParameterConvention::Direct_Unowned);
3289-
(void) param;
3290-
3291-
// Leave a placeholder in the position.
3292-
Args.push_back(ManagedValue::forInContext());
3273+
bool keepGoing = true;
3274+
while (keepGoing) {
3275+
keepGoing = false;
3276+
if (Foreign.async &&
3277+
Foreign.async->completionHandlerParamIndex() == Args.size()) {
3278+
SILParameterInfo param = claimNextParameters(1).front();
3279+
(void)param;
3280+
3281+
// Leave a placeholder in the position. We'll fill this in with a block
3282+
// capturing the current continuation right before we invoke the
3283+
// function.
3284+
// (We can't do this immediately, because evaluating other arguments
3285+
// may require suspending the async task, which is not allowed while its
3286+
// continuation is active.)
3287+
Args.push_back(ManagedValue::forInContext());
3288+
keepGoing = true;
3289+
}
3290+
if (Foreign.error &&
3291+
Foreign.error->getErrorParameterIndex() == Args.size()) {
3292+
SILParameterInfo param = claimNextParameters(1).front();
3293+
assert(param.getConvention() == ParameterConvention::Direct_Unowned);
3294+
(void)param;
3295+
3296+
// Leave a placeholder in the position.
3297+
Args.push_back(ManagedValue::forInContext());
3298+
keepGoing = true;
3299+
}
32933300
}
32943301
}
32953302

@@ -3515,7 +3522,9 @@ struct ParamLowering {
35153522
}
35163523
}
35173524

3518-
if (foreign.error || foreign.async)
3525+
if (foreign.error)
3526+
++count;
3527+
if (foreign.async)
35193528
++count;
35203529

35213530
if (foreign.self.isImportAsMember()) {
@@ -4172,18 +4181,12 @@ ApplyOptions CallEmission::emitArgumentsForNormalApply(
41724181

41734182
args.push_back({});
41744183

4175-
if (!foreign.async || (foreign.async && foreign.error)) {
4176-
// Claim the foreign error argument(s) with the method formal params.
4177-
auto siteForeignError = CalleeTypeInfo::ForeignInfo{foreign.error, {}, {}};
4178-
std::move(*callSite).emit(SGF, origFormalType, substFnType, paramLowering,
4179-
args.back(), delayedArgs, siteForeignError);
4180-
}
4181-
if (foreign.async) {
4182-
// Claim the foreign async argument(s) with the method formal params.
4183-
auto siteForeignAsync = CalleeTypeInfo::ForeignInfo{{}, foreign.async, {}};
4184-
std::move(*callSite).emit(SGF, origFormalType, substFnType, paramLowering,
4185-
args.back(), delayedArgs, siteForeignAsync);
4186-
}
4184+
// Claim the foreign error and/or async arguments when claiming the formal
4185+
// params.
4186+
auto siteForeignError = CalleeTypeInfo::ForeignInfo{foreign.error, foreign.async, {}};
4187+
// Claim the method formal params.
4188+
std::move(*callSite).emit(SGF, origFormalType, substFnType, paramLowering,
4189+
args.back(), delayedArgs, siteForeignError);
41874190
}
41884191

41894192
uncurriedLoc = callSite->Loc;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include <Foundation/Foundation.h>
2+
3+
#pragma clang assume_nonnull begin
4+
5+
typedef void (^CompletionHandler)(int status, NSInteger bytesTransferred);
6+
7+
@interface PFXObject : NSObject
8+
- (BOOL)enqueueFailingRequestWithData:(nullable NSMutableData *)data
9+
error:(NSError *_Nullable *)error
10+
completionHandler:
11+
(nullable CompletionHandler)completionHandler;
12+
- (BOOL)enqueuePassingRequestWithData:(nullable NSMutableData *)data
13+
error:(NSError *_Nullable *)error
14+
completionHandler:
15+
(nullable CompletionHandler)completionHandler;
16+
- (BOOL)enqueueFailingRequestWithData:(nullable NSMutableData *)data
17+
completionTimeout:(NSTimeInterval)completionTimeout
18+
error:(NSError *_Nullable *)error
19+
completionHandler:
20+
(nullable CompletionHandler)completionHandler;
21+
- (BOOL)enqueuePassingRequestWithData:(nullable NSMutableData *)data
22+
completionTimeout:(NSTimeInterval)completionTimeout
23+
error:(NSError *_Nullable *)error
24+
completionHandler:
25+
(nullable CompletionHandler)completionHandler;
26+
@end
27+
28+
#pragma clang assume_nonnull end
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "rdar80704984_3.h"
2+
3+
#pragma clang assume_nonnull begin
4+
5+
@implementation PFXObject
6+
7+
- (BOOL)enqueueFailingRequestWithData:(nullable NSMutableData *)data
8+
error:(NSError *_Nullable *)error
9+
completionHandler:
10+
(nullable CompletionHandler)completionHandler {
11+
*error = [[NSError alloc] initWithDomain:@"d" code:1 userInfo:nil];
12+
return NO;
13+
}
14+
- (BOOL)enqueuePassingRequestWithData:(nullable NSMutableData *)data
15+
error:(NSError *_Nullable *)error
16+
completionHandler:
17+
(nullable CompletionHandler)completionHandler {
18+
dispatch_async(dispatch_get_main_queue(), ^{
19+
completionHandler(0, 2);
20+
});
21+
return YES;
22+
}
23+
24+
- (BOOL)enqueueFailingRequestWithData:(nullable NSMutableData *)data
25+
completionTimeout:(NSTimeInterval)completionTimeout
26+
error:(NSError *_Nullable *)error
27+
completionHandler:
28+
(nullable CompletionHandler)completionHandler {
29+
*error = [[NSError alloc] initWithDomain:@"d" code:2 userInfo:nil];
30+
return NO;
31+
}
32+
- (BOOL)enqueuePassingRequestWithData:(nullable NSMutableData *)data
33+
completionTimeout:(NSTimeInterval)completionTimeout
34+
error:(NSError *_Nullable *)error
35+
completionHandler:
36+
(nullable CompletionHandler)completionHandler {
37+
dispatch_async(dispatch_get_main_queue(), ^{
38+
completionHandler(0, 3);
39+
});
40+
return YES;
41+
}
42+
43+
@end
44+
45+
#pragma clang assume_nonnull end
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-clang %S/Inputs/rdar80704984_3.m -I %S/Inputs -c -o %t/rdar80704984_3.o
3+
// RUN: %target-build-swift -Xfrontend -disable-availability-checking -import-objc-header %S/Inputs/rdar80704984_3.h -Xlinker %t/rdar80704984_3.o -parse-as-library %s -o %t/a.out
4+
// RUN: %target-codesign %t/a.out
5+
// RUN: %target-run %t/a.out | %FileCheck %s
6+
7+
// REQUIRES: executable_test
8+
// REQUIRES: objc_interop
9+
10+
// rdar://82123254
11+
// UNSUPPORTED: use_os_stdlib
12+
// UNSUPPORTED: back_deployment_runtime
13+
14+
func run1(on object: PFXObject) async throws {
15+
do {
16+
_ = try await object.enqueueFailingRequest(with: nil)
17+
}
18+
catch let error {
19+
// CHECK: Domain=d Code=1
20+
print(error)
21+
}
22+
}
23+
24+
func run2(on object: PFXObject) async throws {
25+
// CHECK: (0, 2)
26+
print(try await object.enqueuePassingRequest(with: nil))
27+
28+
}
29+
30+
func run3(on object: PFXObject) async throws {
31+
do {
32+
_ = try await object.enqueueFailingRequest(with: nil, completionTimeout: 57.0)
33+
}
34+
catch let error {
35+
// CHECK: Domain=d Code=2
36+
print(error)
37+
}
38+
}
39+
40+
func run4(on object: PFXObject) async throws {
41+
// CHECK: (0, 3)
42+
print(try await object.enqueuePassingRequest(with: nil, completionTimeout: 57.0))
43+
44+
}
45+
46+
@main struct Main {
47+
static func main() async throws {
48+
let object = PFXObject()
49+
try await run1(on: object)
50+
try await run2(on: object)
51+
try await run3(on: object)
52+
try await run4(on: object)
53+
}
54+
}

0 commit comments

Comments
 (0)