Implement basic support for [weak].

Swift SVN r7041
This commit is contained in:
John McCall
2013-08-08 04:04:51 +00:00
parent 204980bdfd
commit 14cb7001b3
20 changed files with 887 additions and 110 deletions

View File

@@ -561,6 +561,24 @@ namespace {
IGF.emitMemCpy(dest, src, NumProtocols * IGF.IGM.getPointerSize());
}
void emitLoadOfTables(IRGenFunction &IGF, Address existential,
Explosion &out) const {
for (unsigned i = 0; i != NumProtocols; ++i) {
auto tableAddr = IGF.Builder.CreateStructGEP(existential, i,
i * IGF.IGM.getPointerSize());
out.add(IGF.Builder.CreateLoad(tableAddr));
}
}
void emitStoreOfTables(IRGenFunction &IGF, Explosion &in,
Address existential) const {
for (unsigned i = 0; i != NumProtocols; ++i) {
auto tableAddr = IGF.Builder.CreateStructGEP(existential, i,
i * IGF.IGM.getPointerSize());
IGF.Builder.CreateStore(in.claimNext(), tableAddr);
}
}
Address projectValue(IRGenFunction &IGF, Address existential) const {
return IGF.Builder.CreateStructGEP(existential, NumProtocols,
NumProtocols * IGF.IGM.getPointerSize(),
@@ -602,6 +620,43 @@ namespace {
Address valueAddr = projectValue(IGF, existential);
IGF.emitUnknownWeakDestroy(valueAddr);
}
// These explosions must follow the same schema as
// ClassExistentialTypeInfo, i.e. first the tables, then the value.
void weakLoadStrong(IRGenFunction &IGF, Address existential,
Explosion &out) const override {
emitLoadOfTables(IGF, existential, out);
Address valueAddr = projectValue(IGF, existential);
out.add(IGF.emitUnknownWeakLoadStrong(valueAddr,
IGF.IGM.UnknownRefCountedPtrTy));
}
void weakTakeStrong(IRGenFunction &IGF, Address existential,
Explosion &out) const override {
emitLoadOfTables(IGF, existential, out);
Address valueAddr = projectValue(IGF, existential);
out.add(IGF.emitUnknownWeakTakeStrong(valueAddr,
IGF.IGM.UnknownRefCountedPtrTy));
}
void weakInit(IRGenFunction &IGF, Explosion &in,
Address existential) const override {
emitStoreOfTables(IGF, in, existential);
llvm::Value *value = in.claimNext();
assert(value->getType() == IGF.IGM.UnknownRefCountedPtrTy);
Address valueAddr = projectValue(IGF, existential);
IGF.emitUnknownWeakInit(value, valueAddr);
}
void weakAssign(IRGenFunction &IGF, Explosion &in,
Address existential) const override {
emitStoreOfTables(IGF, in, existential);
llvm::Value *value = in.claimNext();
assert(value->getType() == IGF.IGM.UnknownRefCountedPtrTy);
Address valueAddr = projectValue(IGF, existential);
IGF.emitUnknownWeakAssign(value, valueAddr);
}
};
/// A helper class for working with existential types that can be