Skip to content

Commit 15d90d8

Browse files
committed
[IRGen] Pull async polymorphic params from explosion.
Previously, the polymorphic arguments were being discarded. Here, that situation is improved by pulling the polymorphic arguments out of the explosion when having the polymorphic parameters via the NecessaryBindings instance. In order to eanble that, an overload of NecessaryBindings::save is added which takes an explosion and asserts that the polymorphic parameter pulled from the explosion matches with the polymorphic parameter in the NecessaryBindings instance.
1 parent d2fc2c1 commit 15d90d8

File tree

3 files changed

+51
-23
lines changed

3 files changed

+51
-23
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,13 +1989,16 @@ class AsyncCallEmission final : public CallEmission {
19891989
if (layout.hasBindings()) {
19901990
auto bindingLayout = layout.getBindingsLayout();
19911991
auto bindingsAddr = bindingLayout.project(IGF, context, /*offsets*/ None);
1992-
layout.getBindings().save(IGF, bindingsAddr);
1992+
layout.getBindings().save(IGF, bindingsAddr, llArgs);
19931993
}
1994-
// At this point, llArgs contains the arguments that are being passed along
1995-
// via the async context. We can safely drop them on the floor.
1996-
(void)llArgs.claimAll();
1997-
// TODO: Validation: we should be able to check that the contents of llArgs
1998-
// matches what is expected by the layout.
1994+
if (selfValue) {
1995+
auto fieldLayout = layout.getLocalContextLayout();
1996+
Address fieldAddr =
1997+
fieldLayout.project(IGF, context, /*offsets*/ llvm::None);
1998+
auto &ti = cast<LoadableTypeInfo>(fieldLayout.getType());
1999+
ti.initialize(IGF, llArgs, fieldAddr, isOutlined);
2000+
}
2001+
}
19992002
}
20002003
void emitCallToUnmappedExplosion(llvm::CallInst *call, Explosion &out) override {
20012004
SILFunctionConventions fnConv(getCallee().getSubstFunctionType(),

lib/IRGen/GenProto.cpp

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,24 +2728,45 @@ void NecessaryBindings::restore(IRGenFunction &IGF, Address buffer,
27282728
[&](CanType type) { return type;});
27292729
}
27302730

2731+
template <typename Transform>
2732+
static void save(const NecessaryBindings &bindings, IRGenFunction &IGF,
2733+
Address buffer, Transform transform) {
2734+
emitInitOfGenericRequirementsBuffer(
2735+
IGF, bindings.getRequirements().getArrayRef(), buffer,
2736+
[&](GenericRequirement requirement) -> llvm::Value * {
2737+
CanType type = requirement.TypeParameter;
2738+
if (auto protocol = requirement.Protocol) {
2739+
if (auto archetype = dyn_cast<ArchetypeType>(type)) {
2740+
auto wtable =
2741+
emitArchetypeWitnessTableRef(IGF, archetype, protocol);
2742+
return transform(requirement, wtable);
2743+
} else {
2744+
auto conformance = bindings.getConformance(requirement);
2745+
auto wtable = emitWitnessTableRef(IGF, type, conformance);
2746+
return transform(requirement, wtable);
2747+
}
2748+
} else {
2749+
auto metadata = IGF.emitTypeMetadataRef(type);
2750+
return transform(requirement, metadata);
2751+
}
2752+
});
2753+
};
2754+
2755+
void NecessaryBindings::save(IRGenFunction &IGF, Address buffer,
2756+
Explosion &source) const {
2757+
::save(*this, IGF, buffer,
2758+
[&](GenericRequirement requirement,
2759+
llvm::Value *expected) -> llvm::Value * {
2760+
auto *value = source.claimNext();
2761+
assert(value == expected);
2762+
return value;
2763+
});
2764+
}
2765+
27312766
void NecessaryBindings::save(IRGenFunction &IGF, Address buffer) const {
2732-
emitInitOfGenericRequirementsBuffer(IGF, Requirements.getArrayRef(), buffer,
2733-
[&](GenericRequirement requirement) -> llvm::Value* {
2734-
CanType type = requirement.TypeParameter;
2735-
if (auto protocol = requirement.Protocol) {
2736-
if (auto archetype = dyn_cast<ArchetypeType>(type)) {
2737-
auto wtable = emitArchetypeWitnessTableRef(IGF, archetype, protocol);
2738-
return wtable;
2739-
} else {
2740-
auto conformance = getConformance(requirement);
2741-
auto wtable = emitWitnessTableRef(IGF, type, conformance);
2742-
return wtable;
2743-
}
2744-
} else {
2745-
auto metadata = IGF.emitTypeMetadataRef(type);
2746-
return metadata;
2747-
}
2748-
});
2767+
::save(*this, IGF, buffer,
2768+
[](GenericRequirement requirement,
2769+
llvm::Value *value) -> llvm::Value * { return value; });
27492770
}
27502771

27512772
void NecessaryBindings::addTypeMetadata(CanType type) {

lib/IRGen/NecessaryBindings.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include "llvm/ADT/SetVector.h"
2626
#include "swift/AST/Types.h"
2727

28+
#include "Explosion.h"
29+
2830
namespace swift {
2931
class CanType;
3032
enum class MetadataState : size_t;
@@ -94,6 +96,8 @@ class NecessaryBindings {
9496
/// Save the necessary bindings to the given buffer.
9597
void save(IRGenFunction &IGF, Address buffer) const;
9698

99+
void save(IRGenFunction &IGF, Address buffer, Explosion &source) const;
100+
97101
/// Restore the necessary bindings from the given buffer.
98102
void restore(IRGenFunction &IGF, Address buffer, MetadataState state) const;
99103

0 commit comments

Comments
 (0)