Refactor _gatherWrittenGenericParameters

Fix some bugs
This commit is contained in:
Alejandro Alonso
2023-10-11 11:53:56 -07:00
parent 29acda5136
commit a0c8465f0c
4 changed files with 374 additions and 211 deletions

View File

@@ -266,25 +266,6 @@ _buildDemanglingForMetadataPack(MetadataPackPointer pack, size_t count,
return node;
}
/// Demangle the given type name to a generic parameter reference, which
/// will be returned as (depth, index).
static llvm::Optional<std::pair<unsigned, unsigned>>
demangleToGenericParamRef(StringRef typeName) {
StackAllocatedDemangler<1024> demangler;
NodePointer node = demangler.demangleType(typeName);
if (!node)
return llvm::None;
// Find the flat index that the right-hand side refers to.
if (node->getKind() == Demangle::Node::Kind::Type)
node = node->getChild(0);
if (node->getKind() != Demangle::Node::Kind::DependentGenericParamType)
return llvm::None;
return std::pair<unsigned, unsigned>(node->getChild(0)->getIndex(),
node->getChild(1)->getIndex());
}
/// Build an array of demangling trees for each generic argument of the given
/// type metadata.
///
@@ -314,144 +295,74 @@ static bool _buildDemanglingForGenericArgs(
return true;
auto genericArgs = description->getGenericArguments(type);
auto packHeader = generics->getGenericPackShapeHeader();
auto packDescriptors = generics->getGenericPackShapeDescriptors();
unsigned packIndex = 0;
unsigned argIndex = packHeader.NumShapeClasses;
llvm::SmallVector<MetadataOrPack> allGenericArgs;
bool missingWrittenArguments = false;
auto numKeyArgs = 0;
for (auto param : generics->getGenericParams()) {
if (param.hasKeyArgument()) {
numKeyArgs += 1;
}
}
// _gatherWrittenGenericParameters expects to immediately read key generic
// arguments, so skip past the shape classes if we have any.
auto nonShapeClassGenericArgs = genericArgs + packHeader.NumShapeClasses;
llvm::ArrayRef<const void *> genericArgsRef(
reinterpret_cast<const void * const *>(nonShapeClassGenericArgs), numKeyArgs);
if (!_gatherWrittenGenericParameters(description, genericArgsRef,
allGenericArgs, Dem)) {
return false;
}
auto argIndex = 0;
auto packIndex = 0;
for (auto param : generics->getGenericParams()) {
auto genericArg = allGenericArgs[argIndex];
switch (param.getKind()) {
case GenericParamKind::Type:
// The type should have a key argument unless it's been same-typed to
// another type.
if (param.hasKeyArgument()) {
auto genericArg = reinterpret_cast<const Metadata *>(genericArgs[argIndex]);
case GenericParamKind::Type: {
auto metadata = genericArg.getMetadata();
auto genericArgDemangling =
_swift_buildDemanglingForMetadata(metadata, Dem);
auto genericArgDemangling =
_swift_buildDemanglingForMetadata(genericArg, Dem);
if (!genericArgDemangling)
return false;
demangledGenerics.push_back(genericArgDemangling);
++argIndex;
} else {
// Leave a gap for us to fill in by looking at same-type requirements.
demangledGenerics.push_back(nullptr);
missingWrittenArguments = true;
if (!genericArgDemangling) {
return false;
}
demangledGenerics.push_back(genericArgDemangling);
break;
}
case GenericParamKind::TypePack:
if (param.hasKeyArgument()) {
auto packDescriptor = packDescriptors[packIndex];
assert(packDescriptor.Kind == GenericPackKind::Metadata);
assert(packDescriptor.ShapeClass < packHeader.NumShapeClasses);
assert(packDescriptor.Index == argIndex);
case GenericParamKind::TypePack: {
auto packDescriptor = packDescriptors[packIndex];
assert(packDescriptor.Kind == GenericPackKind::Metadata);
assert(packDescriptor.ShapeClass < packHeader.NumShapeClasses);
assert(packDescriptor.Index == argIndex);
MetadataPackPointer pack(genericArgs[argIndex]);
size_t count = reinterpret_cast<size_t>(genericArgs[packDescriptor.ShapeClass]);
MetadataPackPointer pack(genericArg.getMetadataPack());
size_t count = reinterpret_cast<size_t>(genericArgs[packDescriptor.ShapeClass]);
auto genericArgDemangling = _buildDemanglingForMetadataPack(pack, count, Dem);
if (genericArgDemangling == nullptr)
return false;
demangledGenerics.push_back(genericArgDemangling);
++packIndex;
++argIndex;
} else {
// Leave a gap for us to fill in by looking at same-type requirements.
demangledGenerics.push_back(nullptr);
missingWrittenArguments = true;
}
auto genericArgDemangling = _buildDemanglingForMetadataPack(pack, count, Dem);
if (genericArgDemangling == nullptr)
return false;
demangledGenerics.push_back(genericArgDemangling);
packIndex += 1;
break;
}
default:
// We don't know about this kind of parameter.
return false;
}
}
// If there is no follow-up work to do, we're done.
if (!missingWrittenArguments)
return true;
// We have generic arguments that would be written, but have been
// canonicalized away. Use same-type requirements to reconstitute them.
SubstGenericParametersFromMetadata substitutions(
description, reinterpret_cast<const void * const *>(genericArgs));
// Retrieve the mapping information needed for depth/index -> flat index.
llvm::SmallVector<unsigned, 8> genericParamCounts;
(void)_gatherGenericParameterCounts(description, genericParamCounts, Dem);
// Walk through the generic requirements to evaluate same-type
// constraints that are needed to fill in missing generic arguments.
for (const auto &req : generics->getGenericRequirements()) {
// We only care about same-type constraints.
if (req.Flags.getKind() != GenericRequirementKind::SameType)
continue;
auto lhsParam = demangleToGenericParamRef(req.getParam());
if (!lhsParam)
continue;
assert(!req.Flags.isPackRequirement() &&
"Pack requirements not supported here yet");
// If we don't yet have an argument for this parameter, it's a
// same-type-to-concrete constraint.
auto lhsFlatIndex =
_depthIndexToFlatIndex(lhsParam->first, lhsParam->second,
genericParamCounts);
if (!lhsFlatIndex || *lhsFlatIndex >= demangledGenerics.size())
return false;
if (!demangledGenerics[*lhsFlatIndex]) {
// Substitute into the right-hand side.
auto *genericArg =
swift_getTypeByMangledName(MetadataState::Abstract,
req.getMangledTypeName(),
reinterpret_cast<const void * const *>(genericArgs),
[&substitutions](unsigned depth, unsigned index) {
// FIXME: Variadic generics
return substitutions.getMetadata(depth, index).getMetadata();
},
[&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index);
}).getType().getMetadata();
if (!genericArg)
return false;
demangledGenerics[*lhsFlatIndex] =
_swift_buildDemanglingForMetadata(genericArg, Dem);
continue;
}
// If we do have an argument for this parameter, it might be that
// the right-hand side is itself a generic parameter, which means
// we have a same-type constraint A == B where A is already filled in.
auto rhsParam = demangleToGenericParamRef(req.getMangledTypeName());
if (!rhsParam)
return false;
auto rhsFlatIndex =
_depthIndexToFlatIndex(rhsParam->first, rhsParam->second,
genericParamCounts);
if (!rhsFlatIndex || *rhsFlatIndex >= demangledGenerics.size())
return false;
if (demangledGenerics[*rhsFlatIndex] || !demangledGenerics[*lhsFlatIndex])
return false;
demangledGenerics[*rhsFlatIndex] = demangledGenerics[*lhsFlatIndex];
argIndex += 1;
}
return true;
@@ -468,9 +379,14 @@ _buildDemanglingForNominalType(const Metadata *type, Demangle::Demangler &Dem) {
switch (type->getKind()) {
case MetadataKind::Class: {
auto classType = static_cast<const ClassMetadata *>(type);
if (!classType->isTypeMetadata()) {
return nullptr;
}
#if SWIFT_OBJC_INTEROP
// Peek through artificial subclasses.
while (classType->isTypeMetadata() && classType->isArtificialSubclass())
while (classType->isArtificialSubclass())
classType = classType->Superclass;
#endif
description = classType->getDescription();

View File

@@ -1196,11 +1196,6 @@ public:
} // end anonymous namespace
static void _gatherWrittenGenericArgs(
const Metadata *metadata, const TypeContextDescriptor *description,
llvm::SmallVectorImpl<MetadataOrPack> &allGenericArgs,
Demangler &BorrowFrom);
static llvm::Optional<TypeLookupError>
_gatherGenericParameters(const ContextDescriptor *context,
llvm::ArrayRef<MetadataOrPack> genericArgs,
@@ -1278,10 +1273,41 @@ _gatherGenericParameters(const ContextDescriptor *context,
// Compute the set of generic arguments "as written".
llvm::SmallVector<MetadataOrPack, 8> allGenericArgs;
// If we have a parent, gather it's generic arguments "as written".
if (parent) {
_gatherWrittenGenericArgs(parent, parent->getTypeContextDescriptor(),
allGenericArgs, demangler);
auto generics = context->getGenericContext();
assert(generics);
// If we have a parent, gather it's generic arguments "as written". If our
// parent is not generic, there are no generic arguments to add.
if (parent && parent->getTypeContextDescriptor() &&
parent->getTypeContextDescriptor()->getGenericContext()) {
auto parentDescriptor = parent->getTypeContextDescriptor();
auto parentGenerics = parentDescriptor->getGenericContext();
auto packHeader = parentGenerics->getGenericPackShapeHeader();
// _gatherWrittenGenericParameters expects to immediately read key generic
// arguments, so skip past the shape classes if we have any.
auto nonShapeClassGenericArgs = parent->getGenericArgs() + packHeader.NumShapeClasses;
auto numKeyArgs = 0;
for (auto param : parentGenerics->getGenericParams()) {
if (param.hasKeyArgument()) {
numKeyArgs += 1;
}
}
llvm::ArrayRef<const void *> genericArgsRef(
reinterpret_cast<const void * const *>(nonShapeClassGenericArgs),
numKeyArgs);
if (!_gatherWrittenGenericParameters(parentDescriptor,
genericArgsRef,
allGenericArgs, demangler)) {
auto commonString = makeCommonErrorStringGetter();
return TypeLookupError([=] {
return commonString() + "failed to get parent context's written" +
" generic arguments";
});
}
}
// Add the generic arguments we were given.
@@ -1290,8 +1316,6 @@ _gatherGenericParameters(const ContextDescriptor *context,
// Copy the generic arguments needed for metadata from the generic
// arguments "as written".
auto generics = context->getGenericContext();
assert(generics);
{
// Add a placeholder length for each shape class.
auto packShapeHeader = generics->getGenericPackShapeHeader();
@@ -2878,12 +2902,21 @@ const Metadata *swift::_swift_instantiateCheckedGenericMetadata(
DemanglerForRuntimeTypeResolution<StackAllocatedDemangler<2048>> demangler;
llvm::ArrayRef<MetadataOrPack> genericArgsRef(
reinterpret_cast<const MetadataOrPack *>(genericArgs), genericArgsSize);
// _instantiateCheckedGenericMetadata expects generic args to NOT begin with
// shape classes.
llvm::ArrayRef<const void *> genericArgsRef(genericArgs, genericArgsSize);
llvm::SmallVector<MetadataOrPack, 8> writtenGenericArgs;
// If we fail to fill in all of the generic parameters, just fail.
if (!_gatherWrittenGenericParameters(context, genericArgsRef,
writtenGenericArgs, demangler)) {
return nullptr;
}
llvm::SmallVector<unsigned, 8> genericParamCounts;
llvm::SmallVector<const void *, 8> allGenericArgs;
auto result = _gatherGenericParameters(context, genericArgsRef,
auto result = _gatherGenericParameters(context, writtenGenericArgs,
/* parent */ nullptr,
genericParamCounts, allGenericArgs,
demangler);
@@ -3232,76 +3265,72 @@ demangleToGenericParamRef(StringRef typeName) {
node->getChild(1)->getIndex());
}
static void _gatherWrittenGenericArgs(
const Metadata *metadata, const TypeContextDescriptor *description,
llvm::SmallVectorImpl<MetadataOrPack> &allGenericArgs,
Demangler &BorrowFrom) {
if (!description)
return;
auto generics = description->getGenericContext();
if (!generics)
return;
bool swift::_gatherWrittenGenericParameters(
const TypeContextDescriptor *descriptor,
llvm::ArrayRef<const void *> keyArgs,
llvm::SmallVectorImpl<MetadataOrPack> &genericArgs,
Demangle::Demangler &Dem) {
if (!descriptor) {
return false;
}
auto genericContext = descriptor->getGenericContext();
// If the type itself is not generic, then we're done.
if (!genericContext) {
return true;
}
unsigned argIndex = 0;
bool missingWrittenArguments = false;
auto genericArgs = description->getGenericArguments(metadata);
for (auto param : generics->getGenericParams()) {
for (auto param : genericContext->getGenericParams()) {
// The type should have a key argument unless it's been same-typed to
// another type.
if (param.hasKeyArgument()) {
genericArgs.push_back(MetadataOrPack(keyArgs[argIndex]));
argIndex += 1;
} else {
// Leave a gap for us to fill in by looking at same-type requirements.
genericArgs.push_back(MetadataOrPack());
missingWrittenArguments = true;
}
switch (param.getKind()) {
case GenericParamKind::Type:
// The type should have a key argument unless it's been same-typed to
// another type.
if (param.hasKeyArgument()) {
auto genericArg = *genericArgs++;
allGenericArgs.push_back(MetadataOrPack(genericArg));
} else {
// Leave a gap for us to fill in by looking at same type info.
allGenericArgs.push_back(MetadataOrPack());
missingWrittenArguments = true;
}
// Already handled by the above.
break;
case GenericParamKind::TypePack:
// The type should have a key argument unless it's been same-typed to
// another type.
if (param.hasKeyArgument()) {
auto genericArg = reinterpret_cast<const Metadata * const *>(*genericArgs++);
MetadataPackPointer pack(genericArg);
allGenericArgs.push_back(MetadataOrPack(pack));
} else {
// Leave a gap for us to fill in by looking at same type info.
allGenericArgs.push_back(MetadataOrPack());
missingWrittenArguments = true;
}
// Already handled by the above.
break;
default:
// We don't know about this kind of parameter. Create placeholders where
// needed.
if (param.hasKeyArgument()) {
allGenericArgs.push_back(MetadataOrPack());
++genericArgs;
}
break;
// We don't know about this kind of parameter.
return false;
}
}
// If there is no follow-up work to do, we're done.
if (!missingWrittenArguments)
return;
return true;
// We have generic arguments that would be written, but have been
// canonicalized away. Use same-type requirements to reconstitute them.
// Retrieve the mapping information needed for depth/index -> flat index.
llvm::SmallVector<unsigned, 8> genericParamCounts;
(void)_gatherGenericParameterCounts(description, genericParamCounts,
BorrowFrom);
(void)_gatherGenericParameterCounts(descriptor, genericParamCounts, Dem);
SubstGenericParametersFromWrittenArgs substitutions(genericArgs,
genericParamCounts);
bool needToCheckAssociatedSameTypes = false;
// Walk through the generic requirements to evaluate same-type
// constraints that are needed to fill in missing generic arguments.
for (const auto &req : generics->getGenericRequirements()) {
for (const auto &req : genericContext->getGenericRequirements()) {
// We only care about same-type constraints.
if (req.Flags.getKind() != GenericRequirementKind::SameType)
continue;
@@ -3318,23 +3347,25 @@ static void _gatherWrittenGenericArgs(
auto lhsFlatIndex =
_depthIndexToFlatIndex(lhsParam->first, lhsParam->second,
genericParamCounts);
if (!lhsFlatIndex || *lhsFlatIndex >= allGenericArgs.size())
continue;
if (!lhsFlatIndex || *lhsFlatIndex >= genericArgs.size())
return false;
if (!allGenericArgs[*lhsFlatIndex]) {
if (!genericArgs[*lhsFlatIndex]) {
// Substitute into the right-hand side.
SubstGenericParametersFromWrittenArgs substitutions(allGenericArgs,
genericParamCounts);
allGenericArgs[*lhsFlatIndex] =
MetadataOrPack(swift_getTypeByMangledName(MetadataState::Abstract,
auto *genericArg =
swift_getTypeByMangledName(MetadataState::Abstract,
req.getMangledTypeName(),
(const void * const *)allGenericArgs.data(),
keyArgs.data(),
[&substitutions](unsigned depth, unsigned index) {
return substitutions.getMetadata(depth, index).Ptr;
},
[&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index);
}).getType().getMetadata());
}).getType().getMetadata();
if (!genericArg)
return false;
genericArgs[*lhsFlatIndex] = MetadataOrPack(genericArg);
continue;
}
@@ -3342,20 +3373,80 @@ static void _gatherWrittenGenericArgs(
// the right-hand side is itself a generic parameter, which means
// we have a same-type constraint A == B where A is already filled in.
auto rhsParam = demangleToGenericParamRef(req.getMangledTypeName());
if (!rhsParam)
// If the rhs parameter is not a generic parameter itself with
// (depth, index), it could potentially be some associated type. Check it
// again later once we've found all of the other same types.
if (!rhsParam) {
needToCheckAssociatedSameTypes = true;
continue;
}
auto rhsFlatIndex =
_depthIndexToFlatIndex(rhsParam->first, rhsParam->second,
genericParamCounts);
if (!rhsFlatIndex || *rhsFlatIndex >= allGenericArgs.size())
continue;
if (!rhsFlatIndex || *rhsFlatIndex >= genericArgs.size())
return false;
if (allGenericArgs[*rhsFlatIndex] || !allGenericArgs[*lhsFlatIndex])
continue;
if (genericArgs[*rhsFlatIndex] || !genericArgs[*lhsFlatIndex])
return false;
allGenericArgs[*rhsFlatIndex] = allGenericArgs[*lhsFlatIndex];
genericArgs[*rhsFlatIndex] = genericArgs[*lhsFlatIndex];
}
if (!needToCheckAssociatedSameTypes) {
return true;
}
// Once again, loop through our list and look for same type constraints where
// the rhs is an associated type of sorts.
for (const auto &req : genericContext->getGenericRequirements()) {
// We only care about same-type constraints.
if (req.Flags.getKind() != GenericRequirementKind::SameType) {
continue;
}
auto lhsParam = demangleToGenericParamRef(req.getParam());
if (!lhsParam) {
continue;
}
auto lhsFlatIndex =
_depthIndexToFlatIndex(lhsParam->first, lhsParam->second,
genericParamCounts);
if (!lhsFlatIndex || *lhsFlatIndex >= genericArgs.size())
return false;
auto rhsParam =
swift_getTypeByMangledName(MetadataState::Abstract,
req.getMangledTypeName(),
keyArgs.data(),
[&substitutions](unsigned depth, unsigned index) {
return substitutions.getMetadata(depth, index).Ptr;
},
[&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index);
}).getType().getMetadata();
if (!rhsParam) {
return false;
}
// If we already have an argument for the lhs, then just check that it is
// indeed == to the rhs type.
if (auto genericArg = genericArgs[*lhsFlatIndex]) {
if (genericArg.getMetadata() != rhsParam) {
return false;
}
} else {
// If we don't have a lhs yet, then it's just the rhs.
genericArgs[*lhsFlatIndex] = MetadataOrPack(rhsParam);
}
}
return true;
}
struct InitializeDynamicReplacementLookup {

View File

@@ -508,6 +508,17 @@ public:
unsigned depth, unsigned index,
llvm::ArrayRef<unsigned> paramCounts);
/// Gathers all of the written generic parameters needed for
/// '_gatherGenericParameters'. This takes a list of key arguments and fills
/// in the generic arguments with all generic arguments.
///
/// \returns true if the operation succeeded.
bool _gatherWrittenGenericParameters(
const TypeContextDescriptor *descriptor,
llvm::ArrayRef<const void *> keyArgs,
llvm::SmallVectorImpl<MetadataOrPack> &genericArgs,
Demangle::Demangler &Dem);
/// Check the given generic requirements using the given set of generic
/// arguments, collecting the key arguments (e.g., witness tables) for
/// the caller.

View File

@@ -126,4 +126,149 @@ testSuite.test("_swift_checkedCreateType variadic nested with requirements") {
}
}
struct Generic<T> {}
struct Generic2<T, U> {}
struct Generic3<T, U, V> {}
struct Generic4<T, U, V, W> {}
struct Generic5<T, U, V, each W> {}
extension Generic where T == Int {
struct Nested {}
}
extension Generic2 where T == U? {
struct Nested {}
}
extension Generic3 where T == U, U == V.Element, V: Collection {
struct Nested {}
}
extension Generic4 where T == U, U == V.Element, V == W, W: Collection {
struct Nested {}
}
extension Generic5 where T== U, U == V.Element, V: Collection, repeat each W: Equatable {
struct Nested {}
}
testSuite.test("_swift_instantiateCheckedGenericMetadata concrete generic types (same type conretized)") {
let nestedMeta1 = metaPointer(Generic<Int>.Nested.self)
let nestedDesc1 = nestedMeta1.load(
fromByteOffset: MemoryLayout<Int>.size,
as: UnsafeRawPointer.self
)
let genericArgs1: [UnsafeRawPointer?] = []
genericArgs1.withUnsafeBufferPointer {
let nested = _instantiateCheckedGenericMetadata(
nestedDesc1,
UnsafeRawPointer($0.baseAddress!),
UInt($0.count)
)
expectTrue(nested == Generic<Int>.Nested.self)
}
let nestedMeta2 = metaPointer(Generic2<Int?, Int>.Nested.self)
let nestedDesc2 = nestedMeta2.load(
fromByteOffset: MemoryLayout<Int>.size,
as: UnsafeRawPointer.self
)
let genericArgs2 = [metaPointer(String.self)]
genericArgs2.withUnsafeBufferPointer {
let nested = _instantiateCheckedGenericMetadata(
nestedDesc2,
UnsafeRawPointer($0.baseAddress!),
UInt($0.count)
)
expectTrue(nested == Generic2<String?, String>.Nested.self)
}
let nestedMeta3 = metaPointer(Generic3<Int, Int, [Int]>.Nested.self)
let nestedDesc3 = nestedMeta3.load(
fromByteOffset: MemoryLayout<Int>.size,
as: UnsafeRawPointer.self
)
// Fails the constraint `T == V.Element`
let genericArgs3a = [metaPointer(String.self), metaPointer([Int].self)]
genericArgs3a.withUnsafeBufferPointer {
let nested = _instantiateCheckedGenericMetadata(
nestedDesc3,
UnsafeRawPointer($0.baseAddress!),
UInt($0.count)
)
expectNil(nested)
}
// T == String (U)
// U == V.Element
// V: Collection
//
// T == String == V.Element
// V == [String]
let genericArgs3b = [metaPointer(String.self), metaPointer([String].self)]
genericArgs3b.withUnsafeBufferPointer {
let nested = _instantiateCheckedGenericMetadata(
nestedDesc3,
UnsafeRawPointer($0.baseAddress!),
UInt($0.count)
)
expectTrue(nested == Generic3<String, String, [String]>.Nested.self)
}
let nestedMeta4 = metaPointer(Generic4<(), (), [()], [()]>.Nested.self)
let nestedDesc4 = nestedMeta4.load(
fromByteOffset: MemoryLayout<Int>.size,
as: UnsafeRawPointer.self
)
let genericArgs4 = [metaPointer(Int.self), metaPointer([Int].self)]
genericArgs4.withUnsafeBufferPointer {
let nested = _instantiateCheckedGenericMetadata(
nestedDesc4,
UnsafeRawPointer($0.baseAddress!),
UInt($0.count)
)
expectTrue(nested == Generic4<Int, Int, [Int], [Int]>.Nested.self)
}
let nestedMeta5 = metaPointer(Generic5<(), (), [()]>.Nested.self)
let nestedDesc5 = nestedMeta5.load(
fromByteOffset: MemoryLayout<Int>.size,
as: UnsafeRawPointer.self
)
let nested5Pack: [Any.Type] = [String.self, Double.self]
nested5Pack.withUnsafeBufferPointer {
let genericArgs5 = [
metaPointer(Int.self),
metaPointer([Int].self),
allocateMetadataPack(UnsafeRawPointer($0.baseAddress!), UInt($0.count))
]
genericArgs5.withUnsafeBufferPointer {
let nested = _instantiateCheckedGenericMetadata(
nestedDesc5,
UnsafeRawPointer($0.baseAddress!),
UInt($0.count)
)
expectTrue(nested == Generic5<Int, Int, [Int], String, Double>.Nested.self)
}
}
}
runAllTests()