UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
VVMFailureContext.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#if WITH_VERSE_VM || defined(__INTELLISENSE__)
6
7#include "VerseVM/VVMCell.h"
11#include "VerseVM/VVMTree.h"
12#include "VerseVM/VVMType.h"
14
15namespace Verse
16{
17struct FOp;
18struct VFrame;
19struct VTask;
20
22 , TIntrusiveTree<VFailureContext>
23{
26
27 // TODO: We could organize this class to point to a "Rare Data" cell
28 // that has fields that are populated just when leniency is encountered.
29
30 // Base TIntrusiveTree is used to track children FailureContexts. The Next/Prev pointers
31 // will only be populated if we encounter leniency, since they represent sibling
32 // failure contexts. We only remove children from the parent tree after they're
33 // done executing. A failure context is done executing when we run the EndFailureContext
34 // opcode with no suspensions left, or when all suspensions created inside of it are
35 // finished executing, or if failure is encountered.
36
37 // Used to restore state when failure is encountered in *this* failure context.
40 TWriteBarrier<VValue> IncomingEffectToken; // Used to restore the effect token when failure is encountered. Used both during lenient and non-lenient execution.
41 FOp* FailurePC;
42
43 // These fields are used during lenient execution.
46 FOp* ThenPC{nullptr};
47 FOp* DonePC{nullptr};
48
50 bool bFailed{false};
53 FTransaction Transaction;
54
56 {
57 return *new (Context.AllocateFastCell(sizeof(VFailureContext))) VFailureContext(Context, Task, Parent, Frame, IncomingEffectToken, FailurePC);
58 }
59
60 void FinishedExecuting(FAllocationContext Context)
61 {
62 Detach(Context);
63 }
64
66 {
67 // You can't have two sibling transactions that have started. The successor child
68 // transaction can only begin after the predecessor child finishes.
69 // For example, in this Verse code:
70 // if (<ParentTransaction>):
71 // if (<Child1>): ...
72 // if (<Child2>): ...
73 // Child2 can only start after Child1 commits or aborts. Therefore, the list of active
74 // transactions forms a linked list, not a tree (even though we need to track the
75 // tree of failure contexts).
76 //
77 // And because of how transactions work, we need to Abort beginning at the innermost
78 // transaction and moving upwards towards the parent. Since we're just talking about
79 // a linked list here, we count the number of started transactions and just abort the
80 // Context's CurrentTransaction that many times.
81 //
82 // (If for some reason we found that we needed to call Abort on the entire failure context
83 // tree, and needed to maintain that children needed to be aborted before parents, we could
84 // just do a post order traversal to achieve that.)
87 if (FailureContext.Transaction.bHasStarted)
88 {
89 ++NumStartedTransactions;
90 }
91 else
92 {
93 FailureContext.Transaction.Abort(Context);
94 }
95 FailureContext.bFailed = true;
96 });
97
98 for (uint32 I = 0; I < NumStartedTransactions; ++I)
99 {
100 Context.CurrentTransaction()->Abort(Context);
101 }
102 Trail.Abort(Context);
103 }
104
108 , Task(Context, Task)
112 {
113 }
114};
115
116} // namespace Verse
117
118#endif
EForEachResult ForEach(T &Array, const PREDICATE_CLASS &Predicate)
Definition AISense_Sight.cpp:60
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
T * New(FMemStackBase &Mem, int32 Count=1, int32 Align=DEFAULT_ALIGNMENT)
Definition MemStack.h:259
uint32_t uint32
Definition binka_ue_file_header.h:6
FORCEINLINE T * Get(const FObjectPtr &ObjectPtr)
Definition ObjectPtr.h:426
Definition Archive.h:36