Skip to content

Commit fc7bd62

Browse files
committed
[Distributed] Pass arguments from Invocation to HBuffer
1 parent cafc2cc commit fc7bd62

File tree

2 files changed

+75
-12
lines changed

2 files changed

+75
-12
lines changed

stdlib/public/Distributed/DistributedActorSystem.swift

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,12 +224,12 @@ extension DistributedActorSystem {
224224
return UnsafeRawPointer(UnsafeMutablePointer<R>.allocate(capacity: 1))
225225
}
226226

227-
guard let returnType: Any.Type = _getReturnTypeInfo(mangledMethodName: mangledTargetName) else {
227+
guard let returnTypeFromTypeInfo: Any.Type = _getReturnTypeInfo(mangledMethodName: mangledTargetName) else {
228228
throw ExecuteDistributedTargetError(
229229
message: "Failed to decode distributed target return type")
230230
}
231231

232-
guard let resultBuffer = _openExistential(returnType, do: allocateReturnTypeBuffer) else {
232+
guard let resultBuffer = _openExistential(returnTypeFromTypeInfo, do: allocateReturnTypeBuffer) else {
233233
throw ExecuteDistributedTargetError(
234234
message: "Failed to allocate buffer for distributed target return type")
235235
}
@@ -239,7 +239,7 @@ extension DistributedActorSystem {
239239
}
240240

241241
defer {
242-
_openExistential(returnType, do: destroyReturnTypeBuffer)
242+
_openExistential(returnTypeFromTypeInfo, do: destroyReturnTypeBuffer)
243243
}
244244

245245
// Prepare the buffer to decode the argument values into
@@ -250,6 +250,33 @@ extension DistributedActorSystem {
250250
}
251251

252252
do {
253+
// Decode the invocation and pack arguments into the h-buffer
254+
255+
// TODO(distributed): decode the generics info
256+
var argumentDecoder = invocation.makeArgumentDecoder()
257+
var paramIdx = 0
258+
for unsafeRawArgPointer in hargs {
259+
guard paramIdx < paramCount else {
260+
throw ExecuteDistributedTargetError(
261+
message: "Unexpected attempt to decode more parameters than expected: \(paramIdx + 1)")
262+
}
263+
let paramType = paramTypes[paramIdx]
264+
paramIdx += 1
265+
266+
// FIXME(distributed): func doDecode<Arg: SerializationRequirement>(_: Arg.Type) throws {
267+
// FIXME: but how would we call this...?
268+
// FIXME: > type 'Arg' constrained to non-protocol, non-class type 'Self.Invocation.SerializationRequirement'
269+
func doDecodeArgument<Arg>(_: Arg.Type) throws {
270+
let unsafeArgPointer = unsafeRawArgPointer
271+
.bindMemory(to: Arg.self, capacity: 1)
272+
try argumentDecoder.decodeNext(Arg.self, into: unsafeArgPointer)
273+
}
274+
try _openExistential(paramType, do: doDecodeArgument)
275+
}
276+
277+
let returnType = try invocation.decodeReturnType() ?? returnTypeFromTypeInfo
278+
// let errorType = try invocation.decodeErrorType() // TODO: decide how to use?
279+
253280
// Execute the target!
254281
try await _executeDistributedTarget(
255282
on: actor,

test/Distributed/Runtime/distributed_actor_remoteCall.swift

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,15 @@ distributed actor Greeter {
4747
.init(q: "question", a: 42, b: 1, c: 2.0, d: "Lorum ipsum")
4848
}
4949

50+
distributed func echo(name: String) -> String {
51+
return "Echo: \(name)"
52+
}
53+
5054
distributed func enumResult() -> E {
5155
.bar
5256
}
5357

58+
5459
distributed func test(i: Int, s: String) -> String {
5560
return s
5661
}
@@ -142,25 +147,47 @@ struct FakeInvocation: DistributedTargetInvocation {
142147
typealias ArgumentDecoder = FakeArgumentDecoder
143148
typealias SerializationRequirement = Codable
144149

150+
var arguments: [Any] = []
151+
145152
mutating func recordGenericSubstitution<T>(_ type: T.Type) throws {}
146-
mutating func recordArgument<Argument: SerializationRequirement>(argument: Argument) throws {}
153+
mutating func recordArgument<Argument: SerializationRequirement>(argument: Argument) throws {
154+
arguments.append(argument)
155+
}
147156
mutating func recordReturnType<R: SerializationRequirement>(_ type: R.Type) throws {}
148157
mutating func recordErrorType<E: Error>(_ type: E.Type) throws {}
149158
mutating func doneRecording() throws {}
150159

151160
// === Receiving / decoding -------------------------------------------------
152161

153162
mutating func decodeGenericSubstitutions() throws -> [Any.Type] { [] }
154-
func makeArgumentDecoder() -> FakeArgumentDecoder { .init() }
163+
func makeArgumentDecoder() -> FakeArgumentDecoder {
164+
.init(invocation: self)
165+
}
155166
mutating func decodeReturnType() throws -> Any.Type? { nil }
156167
mutating func decodeErrorType() throws -> Any.Type? { nil }
157168

158169
struct FakeArgumentDecoder: DistributedTargetInvocationArgumentDecoder {
159170
typealias SerializationRequirement = Codable
171+
let invocation: FakeInvocation
172+
var index: Int = 0
173+
160174
mutating func decodeNext<Argument>(
161175
_ argumentType: Argument.Type,
162176
into pointer: UnsafeMutablePointer<Argument>
163-
) throws {}
177+
) throws {
178+
guard index < invocation.arguments.count else {
179+
fatalError("Attempted to decode more arguments than stored! Index: \(index), args: \(invocation.arguments)")
180+
}
181+
182+
let anyArgument = invocation.arguments[index]
183+
guard let argument = anyArgument as? Argument else {
184+
fatalError("Cannot cast argument\(anyArgument) to expected \(Argument.self)")
185+
}
186+
187+
print(" > argument: \(argument)")
188+
pointer.pointee = argument
189+
index += 1
190+
}
164191
}
165192
}
166193

@@ -184,7 +211,9 @@ let emptyName = "$s4main7GreeterC5emptyyyFTE"
184211
let helloName = "$s4main7GreeterC5helloSSyFTE"
185212
let answerName = "$s4main7GreeterC6answerSiyFTE"
186213
let largeResultName = "$s4main7GreeterC11largeResultAA11LargeStructVyFTE"
187-
let enumResult = "$s4main7GreeterC10enumResultAA1EOyFTE"
214+
let enumResultName = "$s4main7GreeterC10enumResultAA1EOyFTE"
215+
216+
let echoName = "$s4main7GreeterC4echo4nameS2S_tFTE"
188217

189218
func test() async throws {
190219
let system = FakeActorSystem()
@@ -200,7 +229,6 @@ func test() async throws {
200229
invocation: &invocation,
201230
handler: FakeResultHandler()
202231
)
203-
204232
// CHECK: RETURN: ()
205233

206234
try await system.executeDistributedTarget(
@@ -209,7 +237,6 @@ func test() async throws {
209237
invocation: &invocation,
210238
handler: FakeResultHandler()
211239
)
212-
213240
// CHECK: RETURN: Hello, World!
214241

215242
try await system.executeDistributedTarget(
@@ -218,7 +245,6 @@ func test() async throws {
218245
invocation: &invocation,
219246
handler: FakeResultHandler()
220247
)
221-
222248
// CHECK: RETURN: 42
223249

224250
try await system.executeDistributedTarget(
@@ -227,17 +253,27 @@ func test() async throws {
227253
invocation: &invocation,
228254
handler: FakeResultHandler()
229255
)
230-
231256
// CHECK: RETURN: LargeStruct(q: "question", a: 42, b: 1, c: 2.0, d: "Lorum ipsum")
232257

233258
try await system.executeDistributedTarget(
234259
on: local,
235-
mangledTargetName: enumResult,
260+
mangledTargetName: enumResultName,
236261
invocation: &invocation,
237262
handler: FakeResultHandler()
238263
)
239264
// CHECK: RETURN: bar
240265

266+
var echoInvocation = system.makeInvocation()
267+
try echoInvocation.recordArgument(argument: "Caplin")
268+
try echoInvocation.doneRecording()
269+
try await system.executeDistributedTarget(
270+
on: local,
271+
mangledTargetName: echoName,
272+
invocation: &echoInvocation,
273+
handler: FakeResultHandler()
274+
)
275+
// CHECK: RETURN: Echo: Caplin
276+
241277
// CHECK-NEXT: done
242278
print("done")
243279
}

0 commit comments

Comments
 (0)