mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Distributed] thread-safety also for parameter type metadata
We had fixed this bug in https://github.com/swiftlang/swift/pull/79381 but missed to realize the same problem existed for parameters as well. This corrects the swift_func_getParameterTypeInfo impl, and also removes the entire "unsafe" method, we no longer use it anywhere. Resolves rdar://146679254
This commit is contained in:
@@ -2907,25 +2907,6 @@ static NodePointer getParameterList(NodePointer funcType) {
|
||||
return parameterContainer;
|
||||
}
|
||||
|
||||
static const Metadata *decodeType(TypeDecoder<DecodedMetadataBuilder> &decoder,
|
||||
NodePointer type) {
|
||||
assert(type->getKind() == Node::Kind::Type);
|
||||
|
||||
auto builtTypeOrError = decoder.decodeMangledType(type);
|
||||
|
||||
if (builtTypeOrError.isError()) {
|
||||
auto err = builtTypeOrError.getError();
|
||||
char *errStr = err->copyErrorString();
|
||||
err->freeErrorString(errStr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!builtTypeOrError.getType().isMetadata())
|
||||
return nullptr;
|
||||
|
||||
return builtTypeOrError.getType().getMetadata();
|
||||
}
|
||||
|
||||
SWIFT_CC(swift)
|
||||
SWIFT_RUNTIME_STDLIB_SPI
|
||||
unsigned swift_func_getParameterCount(const char *typeNameStart,
|
||||
@@ -3009,8 +2990,21 @@ swift_func_getParameterTypeInfo(
|
||||
|
||||
SubstGenericParametersFromMetadata substFn(genericEnv, genericArguments);
|
||||
|
||||
DecodedMetadataBuilder builder(
|
||||
demangler,
|
||||
// for each parameter (TupleElement), store it into the provided buffer
|
||||
for (unsigned index = 0; index != typesLength; ++index) {
|
||||
auto nodePointer = parameterList->getChild(index);
|
||||
|
||||
if (nodePointer->getKind() == Node::Kind::TupleElement) {
|
||||
assert(nodePointer->getNumChildren() == 1);
|
||||
nodePointer = nodePointer->getFirstChild();
|
||||
}
|
||||
assert(nodePointer->getKind() == Node::Kind::Type);
|
||||
|
||||
auto request = MetadataRequest(MetadataState::Complete);
|
||||
|
||||
auto typeInfoOrErr = swift_getTypeByMangledNode(
|
||||
request, demangler, nodePointer,
|
||||
/*arguments=*/genericArguments,
|
||||
/*substGenericParam=*/
|
||||
[&substFn](unsigned depth, unsigned index) {
|
||||
return substFn.getMetadata(depth, index).Ptr;
|
||||
@@ -3019,24 +3013,13 @@ swift_func_getParameterTypeInfo(
|
||||
[&substFn](const Metadata *type, unsigned index) {
|
||||
return substFn.getWitnessTable(type, index);
|
||||
});
|
||||
TypeDecoder<DecodedMetadataBuilder> decoder(builder);
|
||||
|
||||
// for each parameter (TupleElement), store it into the provided buffer
|
||||
for (unsigned index = 0; index != typesLength; ++index) {
|
||||
auto *parameter = parameterList->getChild(index);
|
||||
|
||||
if (parameter->getKind() == Node::Kind::TupleElement) {
|
||||
assert(parameter->getNumChildren() == 1);
|
||||
parameter = parameter->getFirstChild();
|
||||
if (typeInfoOrErr.isError()) {
|
||||
return -3; // Failed to decode a type.
|
||||
}
|
||||
|
||||
assert(parameter->getKind() == Node::Kind::Type);
|
||||
|
||||
auto type = decodeType(decoder, parameter);
|
||||
if (!type)
|
||||
return -3; // Failed to decode a type.
|
||||
|
||||
types[index] = type;
|
||||
auto typeInfo = typeInfoOrErr.getType();
|
||||
types[index] = typeInfo.getMetadata();
|
||||
} // end foreach parameter
|
||||
|
||||
return typesLength;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -target %target-swift-5.7-abi-triple %S/../Inputs/FakeDistributedActorSystems.swift
|
||||
// RUN: %target-build-swift -module-name dist -target %target-swift-5.7-abi-triple -parse-as-library -j2 -parse-as-library -plugin-path %swift-plugin-dir -I %t %s %S/../Inputs/FakeDistributedActorSystems.swift -o %t/a.out
|
||||
// RUN: %target-codesign %t/a.out
|
||||
// RUN: %target-run %t/a.out
|
||||
|
||||
// RUN: %target-run %t/a.out PARAMETER_TYPE
|
||||
// RUN: %target-run %t/a.out RETURN_TYPE
|
||||
|
||||
// REQUIRES: executable_test
|
||||
// REQUIRES: concurrency
|
||||
@@ -17,7 +18,6 @@
|
||||
|
||||
import Darwin
|
||||
import Distributed
|
||||
import FakeDistributedActorSystems
|
||||
import Foundation
|
||||
|
||||
typealias DefaultDistributedActorSystem = FakeRoundtripActorSystem
|
||||
@@ -1052,20 +1052,39 @@ struct BigGeneric<T>: Codable {
|
||||
}
|
||||
|
||||
distributed actor D {
|
||||
public distributed func getBigGeneric(_ value: BigGeneric<TypeXXXX>) {}
|
||||
public distributed func getBigGeneric() -> BigGeneric<TypeXXXX> {
|
||||
return BigGeneric()
|
||||
}
|
||||
return BigGeneric()
|
||||
}
|
||||
}
|
||||
|
||||
func attempt(n: Int) {
|
||||
var fname = "$s4dist1DC13getBigGenericAA0cD0VyAA8Type\(n)VGyF"
|
||||
func attempt(_ mode: Mode, n: Int) {
|
||||
var funcName_returnType = "$s4dist1DC13getBigGenericAA0cD0VyAA8Type\(n)VGyF"
|
||||
var funcName_param = "$s4dist1DC13getBigGenericyyAA0cD0VyAA8Type\(n)VGF"
|
||||
|
||||
func tryLookup() {
|
||||
let t = fname.withUTF8 {
|
||||
__getReturnTypeInfo($0.baseAddress!, UInt($0.count), nil, nil)
|
||||
}
|
||||
let t: (any Any.Type)? =
|
||||
switch mode {
|
||||
case .returnType:
|
||||
funcName_returnType.withUTF8 {
|
||||
__getReturnTypeInfo($0.baseAddress!, UInt($0.count), nil, nil)
|
||||
}
|
||||
|
||||
case .paramType:
|
||||
funcName_param.withUTF8 { nameBuf in
|
||||
var type: Any.Type?
|
||||
withUnsafeMutablePointer(to: &type) { typePtr in
|
||||
let ret = __getParameterTypeInfo(nameBuf.baseAddress!, UInt(nameBuf.count), nil, nil, typePtr._rawValue, 1)
|
||||
if ret != 1 {
|
||||
fatalError("Decoded \(ret) parameters, expected 1")
|
||||
}
|
||||
}
|
||||
return type
|
||||
}
|
||||
}
|
||||
|
||||
guard let t else {
|
||||
print("couldn't look up type for: \(fname)")
|
||||
print("couldn't look up type for mode: \(mode)")
|
||||
exit(1)
|
||||
}
|
||||
func examineType<T>(_t: T.Type) {
|
||||
@@ -1081,10 +1100,23 @@ func attempt(n: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
enum Mode: String {
|
||||
case returnType = "RETURN_TYPE"
|
||||
case paramType = "PARAMETER_TYPE"
|
||||
}
|
||||
|
||||
@main struct Main {
|
||||
static func main() {
|
||||
for i in 1000...1999 {
|
||||
attempt(n: i)
|
||||
if CommandLine.arguments.count < 2 {
|
||||
fatalError("Expected explicit mode in command line arguments, was: \(CommandLine.arguments)")
|
||||
}
|
||||
|
||||
let mode = Mode.init(rawValue: CommandLine.arguments.dropFirst().first!)!
|
||||
print("Checking in mode: \(mode)...")
|
||||
|
||||
for i in 1000...1999 {
|
||||
attempt(mode, n: i)
|
||||
}
|
||||
print("Passed in mode: \(mode)!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user