@@ -472,7 +472,7 @@ static llvm::Value *addOptionRecord(IRGenFunction &IGF,
472472}
473473
474474// / Add a task option record to the options list if the given value
475- // / is presernt .
475+ // / is present .
476476template <class RecordTraits >
477477static llvm::Value *maybeAddOptionRecord (IRGenFunction &IGF,
478478 llvm::Value *curRecordPointer,
@@ -645,15 +645,15 @@ struct TaskGroupRecordTraits {
645645 }
646646};
647647
648- struct InitialTaskExecutorRecordTraits {
648+ struct InitialTaskExecutorUnownedRecordTraits {
649649 static StringRef getLabel () {
650- return " task_executor " ;
650+ return " task_executor_unowned " ;
651651 }
652652 static llvm::StructType *getRecordType (IRGenModule &IGM) {
653- return IGM.SwiftInitialTaskExecutorPreferenceTaskOptionRecordTy ;
653+ return IGM.SwiftInitialTaskExecutorUnownedPreferenceTaskOptionRecordTy ;
654654 }
655655 static TaskOptionRecordFlags getRecordFlags () {
656- return TaskOptionRecordFlags (TaskOptionRecordKind::InitialTaskExecutor );
656+ return TaskOptionRecordFlags (TaskOptionRecordKind::InitialTaskExecutorUnowned );
657657 }
658658 static CanType getValueType (ASTContext &ctx) {
659659 return ctx.TheExecutorType ;
@@ -670,6 +670,36 @@ struct InitialTaskExecutorRecordTraits {
670670 }
671671};
672672
673+ struct InitialTaskExecutorOwnedRecordTraits {
674+ static StringRef getLabel () {
675+ return " task_executor_owned" ;
676+ }
677+ static llvm::StructType *getRecordType (IRGenModule &IGM) {
678+ return IGM.SwiftInitialTaskExecutorOwnedPreferenceTaskOptionRecordTy ;
679+ }
680+ static TaskOptionRecordFlags getRecordFlags () {
681+ return TaskOptionRecordFlags (TaskOptionRecordKind::InitialTaskExecutorOwned);
682+ }
683+ static CanType getValueType (ASTContext &ctx) {
684+ return OptionalType::get (ctx.getProtocol (KnownProtocolKind::TaskExecutor)
685+ ->getDeclaredInterfaceType ())
686+ ->getCanonicalType ();
687+ }
688+
689+ void initialize (IRGenFunction &IGF, Address recordAddr,
690+ Explosion &taskExecutor) const {
691+ auto executorRecord =
692+ IGF.Builder .CreateStructGEP (recordAddr, 1 , 2 * IGF.IGM .getPointerSize ());
693+
694+ // This relies on the fact that the HeapObject is directly followed by a
695+ // pointer to the witness table.
696+ IGF.Builder .CreateStore (taskExecutor.claimNext (),
697+ IGF.Builder .CreateStructGEP (executorRecord, 0 , Size ()));
698+ IGF.Builder .CreateStore (taskExecutor.claimNext (),
699+ IGF.Builder .CreateStructGEP (executorRecord, 1 , Size ()));
700+ }
701+ };
702+
673703} // end anonymous namespace
674704
675705static llvm::Value *
@@ -693,15 +723,25 @@ maybeAddInitialTaskExecutorOptionRecord(IRGenFunction &IGF,
693723 llvm::Value *prevOptions,
694724 OptionalExplosion &taskExecutor) {
695725 return maybeAddOptionRecord (IGF, prevOptions,
696- InitialTaskExecutorRecordTraits (),
726+ InitialTaskExecutorUnownedRecordTraits (),
697727 taskExecutor);
698728}
699729
730+ static llvm::Value *
731+ maybeAddInitialTaskExecutorOwnedOptionRecord (IRGenFunction &IGF,
732+ llvm::Value *prevOptions,
733+ OptionalExplosion &taskExecutorExistential) {
734+ return maybeAddOptionRecord (IGF, prevOptions,
735+ InitialTaskExecutorOwnedRecordTraits (),
736+ taskExecutorExistential);
737+ }
738+
700739std::pair<llvm::Value *, llvm::Value *>
701740irgen::emitTaskCreate (IRGenFunction &IGF, llvm::Value *flags,
702741 OptionalExplosion &serialExecutor,
703742 OptionalExplosion &taskGroup,
704- OptionalExplosion &taskExecutor,
743+ OptionalExplosion &taskExecutorUnowned,
744+ OptionalExplosion &taskExecutorExistential,
705745 Explosion &taskFunction,
706746 SubstitutionMap subs) {
707747 llvm::Value *taskOptions =
@@ -729,8 +769,14 @@ irgen::emitTaskCreate(IRGenFunction &IGF, llvm::Value *flags,
729769 taskOptions = maybeAddTaskGroupOptionRecord (IGF, taskOptions, taskGroup);
730770
731771 // Add an option record for the initial task executor, if present.
732- taskOptions =
733- maybeAddInitialTaskExecutorOptionRecord (IGF, taskOptions, taskExecutor);
772+ {
773+ // Deprecated: This is the UnownedTaskExecutor? which is NOT consuming
774+ taskOptions = maybeAddInitialTaskExecutorOptionRecord (
775+ IGF, taskOptions, taskExecutorUnowned);
776+ // Take an (any TaskExecutor)? which we retain until task has completed
777+ taskOptions = maybeAddInitialTaskExecutorOwnedOptionRecord (
778+ IGF, taskOptions, taskExecutorExistential);
779+ }
734780
735781 // In embedded Swift, create and pass result type info.
736782 taskOptions = maybeAddEmbeddedSwiftResultTypeInfo (IGF, taskOptions, resultType);
0 commit comments