2020-01-22 17:58:55 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "RigVMCompiler/RigVMCompiler.h"
# include "RigVMModel/RigVMController.h"
# include "RigVMCore/RigVMExecuteContext.h"
2022-03-31 14:40:13 -04:00
# include "RigVMCore/RigVMNativized.h"
2020-01-22 17:58:55 -05:00
# include "RigVMDeveloperModule.h"
# include "UObject/PropertyPortFlags.h"
2022-03-16 03:29:38 -04:00
# include "UObject/Interface.h"
2020-01-22 17:58:55 -05:00
# include "Stats/StatsHierarchical.h"
2021-11-18 08:00:07 -05:00
# include "RigVMTypeUtils.h"
2020-01-22 17:58:55 -05:00
class FRigVMCompilerImportErrorContext : public FOutputDevice
{
public :
URigVMCompiler * Compiler ;
int32 NumErrors ;
FRigVMCompilerImportErrorContext ( URigVMCompiler * InCompiler )
: FOutputDevice ( )
, Compiler ( InCompiler )
, NumErrors ( 0 )
{
}
virtual void Serialize ( const TCHAR * V , ELogVerbosity : : Type Verbosity , const class FName & Category ) override
{
switch ( Verbosity )
{
case ELogVerbosity : : Error :
case ELogVerbosity : : Fatal :
{
Compiler - > ReportError ( V ) ;
break ;
}
case ELogVerbosity : : Warning :
{
Compiler - > ReportWarning ( V ) ;
break ;
}
default :
{
Compiler - > ReportInfo ( V ) ;
break ;
}
}
NumErrors + + ;
}
} ;
FRigVMCompileSettings : : FRigVMCompileSettings ( )
: SurpressInfoMessages ( true )
, SurpressWarnings ( false )
, SurpressErrors ( false )
, EnablePinWatches ( true )
2021-05-14 02:36:03 -04:00
, IsPreprocessorPhase ( false )
2020-01-22 17:58:55 -05:00
, ASTSettings ( FRigVMParserASTSettings : : Optimized ( ) )
2020-09-24 00:43:27 -04:00
, SetupNodeInstructionIndex ( true )
2020-01-22 17:58:55 -05:00
{
}
2021-07-27 14:04:39 -04:00
FRigVMOperand FRigVMCompilerWorkData : : AddProperty (
ERigVMMemoryType InMemoryType ,
const FName & InName ,
const FString & InCPPType ,
UObject * InCPPTypeObject ,
const FString & InDefaultValue )
2020-01-22 17:58:55 -05:00
{
2021-07-27 14:04:39 -04:00
check ( bSetupMemory ) ;
2021-07-28 03:35:30 -04:00
FRigVMPropertyDescription Description ( InName , InCPPType , InCPPTypeObject , InDefaultValue ) ;
2021-07-27 14:04:39 -04:00
2021-07-28 03:35:30 -04:00
TArray < FRigVMPropertyDescription > & PropertyArray = PropertyDescriptions . FindOrAdd ( InMemoryType ) ;
2021-07-27 14:04:39 -04:00
const int32 PropertyIndex = PropertyArray . Add ( Description ) ;
return FRigVMOperand ( InMemoryType , PropertyIndex ) ;
2020-01-22 17:58:55 -05:00
}
2021-07-27 14:04:39 -04:00
FRigVMOperand FRigVMCompilerWorkData : : FindProperty ( ERigVMMemoryType InMemoryType , const FName & InName )
2020-01-22 17:58:55 -05:00
{
2021-07-28 03:35:30 -04:00
TArray < FRigVMPropertyDescription > * PropertyArray = PropertyDescriptions . Find ( InMemoryType ) ;
2021-07-27 14:04:39 -04:00
if ( PropertyArray )
2020-01-22 17:58:55 -05:00
{
2021-07-27 14:04:39 -04:00
for ( int32 Index = 0 ; Index < PropertyArray - > Num ( ) ; Index + + )
{
if ( PropertyArray - > operator [ ] ( Index ) . Name = = InName )
{
return FRigVMOperand ( InMemoryType , Index ) ;
}
}
2020-01-22 17:58:55 -05:00
}
2021-07-27 14:04:39 -04:00
return FRigVMOperand ( ) ;
2020-01-22 17:58:55 -05:00
}
2021-07-28 03:35:30 -04:00
FRigVMPropertyDescription FRigVMCompilerWorkData : : GetProperty ( const FRigVMOperand & InOperand )
2020-09-24 00:43:27 -04:00
{
2021-07-28 03:35:30 -04:00
TArray < FRigVMPropertyDescription > * PropertyArray = PropertyDescriptions . Find ( InOperand . GetMemoryType ( ) ) ;
2021-07-27 14:04:39 -04:00
if ( PropertyArray )
{
if ( PropertyArray - > IsValidIndex ( InOperand . GetRegisterIndex ( ) ) )
{
return PropertyArray - > operator [ ] ( InOperand . GetRegisterIndex ( ) ) ;
}
}
2021-07-28 03:35:30 -04:00
return FRigVMPropertyDescription ( ) ;
2020-09-24 00:43:27 -04:00
}
2021-08-03 06:19:44 -04:00
int32 FRigVMCompilerWorkData : : FindOrAddPropertyPath ( const FRigVMOperand & InOperand , const FString & InHeadCPPType , const FString & InSegmentPath )
2021-07-27 14:04:39 -04:00
{
2021-07-29 14:29:52 -04:00
if ( InSegmentPath . IsEmpty ( ) )
2021-07-27 14:04:39 -04:00
{
2021-07-29 14:29:52 -04:00
return INDEX_NONE ;
2021-07-28 03:35:30 -04:00
}
TArray < FRigVMPropertyPathDescription > & Descriptions = PropertyPathDescriptions . FindOrAdd ( InOperand . GetMemoryType ( ) ) ;
for ( int32 Index = 0 ; Index < Descriptions . Num ( ) ; Index + + )
{
const FRigVMPropertyPathDescription & Description = Descriptions [ Index ] ;
2021-08-03 06:19:44 -04:00
if ( Description . HeadCPPType = = InHeadCPPType & & Description . SegmentPath = = InSegmentPath )
2021-07-27 14:04:39 -04:00
{
return Index ;
}
}
2021-08-03 06:19:44 -04:00
return Descriptions . Add ( FRigVMPropertyPathDescription ( InOperand . GetRegisterIndex ( ) , InHeadCPPType , InSegmentPath ) ) ;
2021-07-27 14:04:39 -04:00
}
2020-01-22 17:58:55 -05:00
URigVMCompiler : : URigVMCompiler ( )
{
}
2022-05-31 04:27:20 -04:00
bool URigVMCompiler : : Compile ( TArray < URigVMGraph * > InGraphs , URigVMController * InController , URigVM * OutVM , const TArray < FRigVMExternalVariable > & InExternalVariables , const TArray < FRigVMUserDataArray > & InRigVMUserData , TMap < FString , FRigVMOperand > * OutOperands , TSharedPtr < FRigVMParserAST > InAST )
2020-01-22 17:58:55 -05:00
{
2022-05-31 04:27:20 -04:00
if ( InGraphs . IsEmpty ( ) | | InGraphs . Contains ( nullptr ) )
2020-01-22 17:58:55 -05:00
{
ReportError ( TEXT ( " Provided graph is nullptr. " ) ) ;
return false ;
}
2022-05-31 04:27:20 -04:00
2020-01-22 17:58:55 -05:00
if ( OutVM = = nullptr )
{
ReportError ( TEXT ( " Provided vm is nullptr. " ) ) ;
return false ;
}
2022-05-31 04:27:20 -04:00
for ( int32 Index = 1 ; Index < InGraphs . Num ( ) ; Index + + )
{
if ( InGraphs [ 0 ] - > GetOuter ( ) ! = InGraphs [ Index ] - > GetOuter ( ) )
{
ReportError ( TEXT ( " Provided graphs don't share a common outer / package. " ) ) ;
return false ;
}
}
2022-03-31 14:40:13 -04:00
if ( OutVM - > GetClass ( ) - > IsChildOf ( URigVMNativized : : StaticClass ( ) ) )
{
ReportError ( TEXT ( " Provided vm is nativized. " ) ) ;
return false ;
}
2020-01-22 17:58:55 -05:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2020-09-24 00:43:27 -04:00
TArray < FRigVMUserDataArray > UserData = InRigVMUserData ;
if ( UserData . Num ( ) = = 0 )
{
UserData . Add ( FRigVMUserDataArray ( ) ) ;
}
2020-01-22 17:58:55 -05:00
OutVM - > Reset ( ) ;
TMap < FString , FRigVMOperand > LocalOperands ;
if ( OutOperands = = nullptr )
{
OutOperands = & LocalOperands ;
}
OutOperands - > Reset ( ) ;
2021-04-07 13:09:20 -04:00
# if WITH_EDITOR
// traverse all graphs and try to clear out orphan pins
2021-04-27 03:19:42 -04:00
// also check on function references with unmapped variables
2021-04-07 13:09:20 -04:00
TArray < URigVMGraph * > VisitedGraphs ;
2022-05-31 04:27:20 -04:00
VisitedGraphs . Append ( InGraphs ) ;
2021-04-07 17:24:36 -04:00
2021-09-22 08:06:30 -04:00
bool bEncounteredGraphError = false ;
2021-04-07 13:09:20 -04:00
for ( int32 GraphIndex = 0 ; GraphIndex < VisitedGraphs . Num ( ) ; GraphIndex + + )
{
URigVMGraph * VisitedGraph = VisitedGraphs [ GraphIndex ] ;
2022-01-13 22:49:09 -05:00
{
FRigVMControllerGraphGuard Guard ( InController , VisitedGraph , false ) ;
// make sure variables are up to date before validating other things.
// that is, make sure their cpp type and type object agree with each other
InController - > EnsureLocalVariableValidity ( ) ;
}
2021-04-07 13:09:20 -04:00
for ( URigVMNode * ModelNode : VisitedGraph - > GetNodes ( ) )
{
2021-04-13 12:03:23 -04:00
FRigVMControllerGraphGuard Guard ( InController , VisitedGraph , false ) ;
2022-01-13 22:49:09 -05:00
// make sure pins are up to date before validating other things.
// that is, make sure their cpp type and type object agree with each other
for ( URigVMPin * Pin : ModelNode - > Pins )
{
if ( ! URigVMController : : EnsurePinValidity ( Pin , true ) )
{
return false ;
}
}
2021-04-07 13:09:20 -04:00
if ( ! InController - > RemoveUnusedOrphanedPins ( ModelNode , true ) )
{
static const FString LinkedMessage = TEXT ( " Node @@ uses pins that no longer exist. Please rewire the links and re-compile. " ) ;
Settings . ASTSettings . Report ( EMessageSeverity : : Error , ModelNode , LinkedMessage ) ;
2021-09-22 08:06:30 -04:00
bEncounteredGraphError = true ;
2021-04-07 13:09:20 -04:00
}
2021-12-01 06:29:29 -05:00
// avoid function reference related validation for temp assets, a temp asset may get generated during
// certain content validation process. It is usually just a simple file-level copy of the source asset
// so these references are usually not fixed-up properly. Thus, it is meaningless to validate them.
if ( ! ModelNode - > GetPackage ( ) - > GetName ( ) . StartsWith ( TEXT ( " /Temp/ " ) ) )
2021-04-27 03:19:42 -04:00
{
2021-12-01 06:29:29 -05:00
if ( URigVMFunctionReferenceNode * FunctionReferenceNode = Cast < URigVMFunctionReferenceNode > ( ModelNode ) )
2021-04-27 03:19:42 -04:00
{
2021-12-01 06:29:29 -05:00
if ( ! FunctionReferenceNode - > IsFullyRemapped ( ) )
{
static const FString UnmappedMessage = TEXT ( " Node @@ has unmapped variables. Please adjust the node and re-compile. " ) ;
Settings . ASTSettings . Report ( EMessageSeverity : : Error , ModelNode , UnmappedMessage ) ;
bEncounteredGraphError = true ;
}
2021-04-27 03:19:42 -04:00
}
}
2021-08-31 03:36:39 -04:00
if ( ModelNode - > IsA < URigVMFunctionEntryNode > ( ) | | ModelNode - > IsA < URigVMFunctionReturnNode > ( ) )
{
2021-09-22 08:06:30 -04:00
for ( URigVMPin * ExecutePin : ModelNode - > Pins )
2021-08-31 03:36:39 -04:00
{
2021-09-22 08:06:30 -04:00
if ( ExecutePin - > IsExecuteContext ( ) )
2021-08-31 03:36:39 -04:00
{
2021-09-22 08:06:30 -04:00
if ( ExecutePin - > GetLinks ( ) . Num ( ) = = 0 )
{
static const FString UnlinkedExecuteMessage = TEXT ( " Node @@ has an unconnected Execute pin. \n The function might cause unexpected behavior. " ) ;
Settings . ASTSettings . Report ( EMessageSeverity : : Error , ModelNode , UnlinkedExecuteMessage ) ;
bEncounteredGraphError = true ;
}
2021-08-31 03:36:39 -04:00
}
}
}
2021-04-07 13:09:20 -04:00
if ( URigVMLibraryNode * LibraryNode = Cast < URigVMLibraryNode > ( ModelNode ) )
{
if ( URigVMGraph * ContainedGraph = LibraryNode - > GetContainedGraph ( ) )
{
VisitedGraphs . AddUnique ( ContainedGraph ) ;
}
}
2021-08-26 06:58:05 -04:00
2021-10-25 20:05:28 -04:00
// for variable let's validate ill formed variable nodes
if ( URigVMVariableNode * VariableNode = Cast < URigVMVariableNode > ( ModelNode ) )
{
static const FString IllFormedVariableNodeMessage = TEXT ( " Variable Node @@ is ill-formed (pin type doesn't match the variable type). \n Consider to recreate the node. " ) ;
const FRigVMGraphVariableDescription VariableDescription = VariableNode - > GetVariableDescription ( ) ;
const TArray < FRigVMGraphVariableDescription > LocalVariables = VisitedGraph - > GetLocalVariables ( true ) ;
bool bFoundVariable = false ;
for ( const FRigVMGraphVariableDescription & LocalVariable : LocalVariables )
{
if ( LocalVariable . Name = = VariableDescription . Name )
{
bFoundVariable = true ;
if ( LocalVariable . CPPType ! = VariableDescription . CPPType | |
LocalVariable . CPPTypeObject ! = VariableDescription . CPPTypeObject )
{
Settings . ASTSettings . Report ( EMessageSeverity : : Error , ModelNode , IllFormedVariableNodeMessage ) ;
bEncounteredGraphError = true ;
}
}
}
// if the variable is not a local variable, let's test against the external variables.
if ( ! bFoundVariable )
{
const FRigVMExternalVariable ExternalVariable = VariableDescription . ToExternalVariable ( ) ;
for ( const FRigVMExternalVariable & InExternalVariable : InExternalVariables )
{
if ( InExternalVariable . Name = = ExternalVariable . Name )
{
bFoundVariable = true ;
if ( InExternalVariable . TypeName ! = ExternalVariable . TypeName | |
InExternalVariable . TypeObject ! = ExternalVariable . TypeObject | |
InExternalVariable . bIsArray ! = ExternalVariable . bIsArray )
{
Settings . ASTSettings . Report ( EMessageSeverity : : Error , ModelNode , IllFormedVariableNodeMessage ) ;
bEncounteredGraphError = true ;
}
}
}
}
2022-03-16 03:28:36 -04:00
if ( VariableDescription . CPPTypeObject & & ! RigVMCore : : SupportsUObjects ( ) )
{
2022-04-06 08:26:45 -04:00
if ( VariableDescription . CPPTypeObject - > IsA < UClass > ( ) )
2022-03-16 03:28:36 -04:00
{
2022-04-06 08:26:45 -04:00
static const FString InvalidObjectTypeMessage = TEXT ( " Variable Node @@ uses an unsupported UClass type. " ) ;
Settings . ASTSettings . Report ( EMessageSeverity : : Error , ModelNode , InvalidObjectTypeMessage ) ;
bEncounteredGraphError = true ;
}
}
if ( VariableDescription . CPPTypeObject & & ! RigVMCore : : SupportsUInterfaces ( ) )
{
if ( VariableDescription . CPPTypeObject - > IsA < UInterface > ( ) )
{
static const FString InvalidObjectTypeMessage = TEXT ( " Variable Node @@ uses an unsupported UInterface type. " ) ;
2022-03-16 03:28:36 -04:00
Settings . ASTSettings . Report ( EMessageSeverity : : Error , ModelNode , InvalidObjectTypeMessage ) ;
bEncounteredGraphError = true ;
}
}
2021-10-25 20:05:28 -04:00
}
2021-08-26 06:58:05 -04:00
for ( URigVMPin * Pin : ModelNode - > Pins )
{
if ( ! URigVMController : : EnsurePinValidity ( Pin , true ) )
{
return false ;
}
}
2021-04-07 13:09:20 -04:00
}
}
2021-04-07 17:24:36 -04:00
2021-09-22 08:06:30 -04:00
if ( bEncounteredGraphError )
2021-04-07 17:24:36 -04:00
{
return false ;
}
2021-04-07 13:09:20 -04:00
# endif
2020-09-24 00:43:27 -04:00
OutVM - > ClearExternalVariables ( ) ;
2021-07-29 14:29:52 -04:00
2020-09-24 00:43:27 -04:00
for ( const FRigVMExternalVariable & ExternalVariable : InExternalVariables )
{
2021-07-29 14:29:52 -04:00
check ( ExternalVariable . Property ) ;
2020-09-24 00:43:27 -04:00
FRigVMOperand Operand = OutVM - > AddExternalVariable ( ExternalVariable ) ;
FString Hash = FString : : Printf ( TEXT ( " Variable::%s " ) , * ExternalVariable . Name . ToString ( ) ) ;
OutOperands - > Add ( Hash , Operand ) ;
}
2022-03-31 14:40:13 -04:00
FRigVMCompilerWorkData WorkData ;
WorkData . AST = InAST ;
if ( ! WorkData . AST . IsValid ( ) )
2020-09-24 00:43:27 -04:00
{
2022-05-31 04:27:20 -04:00
WorkData . AST = MakeShareable ( new FRigVMParserAST ( InGraphs , InController , Settings . ASTSettings , InExternalVariables , UserData ) ) ;
for ( URigVMGraph * Graph : InGraphs )
{
Graph - > RuntimeAST = WorkData . AST ;
}
2021-01-12 06:47:41 -04:00
# if UE_BUILD_DEBUG
2020-09-24 00:43:27 -04:00
//UE_LOG(LogRigVMDeveloper, Display, TEXT("%s"), *AST->DumpDot());
2021-01-12 06:47:41 -04:00
# endif
2020-09-24 00:43:27 -04:00
}
2022-03-31 14:40:13 -04:00
ensure ( WorkData . AST . IsValid ( ) ) ;
2020-01-22 17:58:55 -05:00
WorkData . VM = OutVM ;
WorkData . PinPathToOperand = OutOperands ;
2020-09-24 00:43:27 -04:00
WorkData . RigVMUserData = UserData [ 0 ] ;
2020-01-22 17:58:55 -05:00
WorkData . bSetupMemory = true ;
2022-03-31 14:40:13 -04:00
WorkData . ProxySources = & WorkData . AST - > SharedOperandPins ;
2021-11-18 12:28:07 -05:00
// tbd: do we need this only when we have no pins?
//if(!WorkData.WatchedPins.IsEmpty())
{
// create the inverse map for the proxies
WorkData . ProxyTargets . Reserve ( WorkData . ProxySources - > Num ( ) ) ;
for ( const TPair < FRigVMASTProxy , FRigVMASTProxy > & Pair : * WorkData . ProxySources )
{
WorkData . ProxyTargets . FindOrAdd ( Pair . Value ) . Add ( Pair . Key ) ;
}
}
2020-09-24 00:43:27 -04:00
UE_LOG_RIGVMMEMORY ( TEXT ( " RigVMCompiler: Begin '%s'... " ) , * InGraph - > GetPathName ( ) ) ;
2020-01-22 17:58:55 -05:00
2021-09-06 04:39:25 -04:00
# if WITH_EDITOR
// If in editor, make sure we visit all the graphs to initialize local variables
// in case the user wants to edit default values
2022-05-31 04:27:20 -04:00
URigVMFunctionLibrary * FunctionLibrary = InGraphs [ 0 ] - > GetDefaultFunctionLibrary ( ) ;
2021-09-07 06:09:01 -04:00
if ( FunctionLibrary )
2021-09-06 04:39:25 -04:00
{
2021-09-07 06:09:01 -04:00
for ( URigVMLibraryNode * LibraryNode : FunctionLibrary - > GetFunctions ( ) )
2021-09-06 04:39:25 -04:00
{
2022-01-13 22:49:09 -05:00
{
FRigVMControllerGraphGuard Guard ( InController , LibraryNode - > GetContainedGraph ( ) , false ) ;
// make sure variables are up to date before validating other things.
// that is, make sure their cpp type and type object agree with each other
InController - > EnsureLocalVariableValidity ( ) ;
}
2021-09-07 06:09:01 -04:00
for ( FRigVMGraphVariableDescription & Variable : LibraryNode - > GetContainedGraph ( ) - > LocalVariables )
{
2022-05-31 04:27:20 -04:00
FString Path = FString : : Printf ( TEXT ( " LocalVariableDefault::%s|%s::Const " ) , * LibraryNode - > GetContainedGraph ( ) - > GetGraphName ( ) , * Variable . Name . ToString ( ) ) ;
2021-09-07 06:09:01 -04:00
FRigVMOperand Operand = WorkData . AddProperty ( ERigVMMemoryType : : Literal , * Path , Variable . CPPType , Variable . CPPTypeObject , Variable . DefaultValue ) ;
WorkData . PinPathToOperand - > Add ( Path , Operand ) ;
2021-09-14 10:59:08 -04:00
for ( const FRigVMExternalVariable & ExternalVariable : InExternalVariables )
{
if ( ExternalVariable . Name = = Variable . Name )
{
ReportWarningf ( TEXT ( " Blueprint variable %s is being shadowed by a local variable in function %s " ) , * ExternalVariable . Name . ToString ( ) , * LibraryNode - > GetName ( ) ) ;
}
}
2021-09-07 06:09:01 -04:00
}
2021-09-06 04:39:25 -04:00
}
}
# endif
2021-05-11 17:13:58 -04:00
// Look for all local variables to create the register with the default value in the literal memory
int32 IndexLocalVariable = 0 ;
for ( URigVMGraph * VisitedGraph : VisitedGraphs )
{
for ( const FRigVMGraphVariableDescription & LocalVariable : VisitedGraph - > LocalVariables )
{
2021-11-15 05:32:56 -05:00
auto AddDefaultValueOperand = [ & ] ( URigVMPin * Pin )
{
FRigVMASTProxy PinProxy = FRigVMASTProxy : : MakeFromUObject ( Pin ) ;
2022-03-31 14:40:13 -04:00
FRigVMVarExprAST * TempVarExpr = WorkData . AST - > MakeExpr < FRigVMVarExprAST > ( FRigVMExprAST : : EType : : Literal , PinProxy ) ;
2021-11-15 05:32:56 -05:00
FRigVMOperand Operand = FindOrAddRegister ( TempVarExpr , WorkData , false ) ;
check ( Operand . GetMemoryType ( ) = = ERigVMMemoryType : : Literal ) ;
TArray < FRigVMPropertyDescription > & LiteralProperties = WorkData . PropertyDescriptions . FindChecked ( Operand . GetMemoryType ( ) ) ;
LiteralProperties [ Operand . GetRegisterIndex ( ) ] . DefaultValue = LocalVariable . DefaultValue ;
} ;
// To create the default value in the literal memory, we need to find a pin in a variable node (or bounded to a local variable) that
2021-05-11 17:13:58 -04:00
// uses this local variable
for ( URigVMNode * Node : VisitedGraph - > GetNodes ( ) )
{
if ( URigVMVariableNode * VariableNode = Cast < URigVMVariableNode > ( Node ) )
{
if ( URigVMPin * Pin = VariableNode - > FindPin ( URigVMVariableNode : : VariableName ) )
{
if ( Pin - > GetDefaultValue ( ) = = LocalVariable . Name . ToString ( ) )
{
URigVMPin * ValuePin = VariableNode - > FindPin ( URigVMVariableNode : : ValueName ) ;
2021-11-15 05:32:56 -05:00
AddDefaultValueOperand ( ValuePin ) ;
2021-05-11 17:13:58 -04:00
break ;
}
}
}
}
}
}
2021-07-29 14:29:52 -04:00
if ( Settings . EnablePinWatches )
{
for ( int32 GraphIndex = 0 ; GraphIndex < VisitedGraphs . Num ( ) ; GraphIndex + + )
{
URigVMGraph * VisitedGraph = VisitedGraphs [ GraphIndex ] ;
for ( URigVMNode * ModelNode : VisitedGraph - > GetNodes ( ) )
{
for ( URigVMPin * ModelPin : ModelNode - > GetPins ( ) )
{
if ( ModelPin - > RequiresWatch ( true ) )
{
WorkData . WatchedPins . AddUnique ( ModelPin ) ;
}
}
}
}
}
2020-04-07 04:27:49 -04:00
WorkData . ExprComplete . Reset ( ) ;
2022-03-31 14:40:13 -04:00
for ( FRigVMExprAST * RootExpr : * WorkData . AST )
2020-04-07 04:27:49 -04:00
{
TraverseExpression ( RootExpr , WorkData ) ;
}
2021-07-29 14:29:52 -04:00
if ( WorkData . WatchedPins . Num ( ) > 0 )
{
for ( int32 GraphIndex = 0 ; GraphIndex < VisitedGraphs . Num ( ) ; GraphIndex + + )
{
URigVMGraph * VisitedGraph = VisitedGraphs [ GraphIndex ] ;
for ( URigVMNode * ModelNode : VisitedGraph - > GetNodes ( ) )
{
for ( URigVMPin * ModelPin : ModelNode - > GetPins ( ) )
{
if ( ModelPin - > GetDirection ( ) = = ERigVMPinDirection : : Input )
{
if ( ModelPin - > GetSourceLinks ( true ) . Num ( ) = = 0 )
{
continue ;
}
}
FRigVMASTProxy PinProxy = FRigVMASTProxy : : MakeFromUObject ( ModelPin ) ;
FRigVMVarExprAST TempVarExpr ( FRigVMExprAST : : EType : : Var , PinProxy ) ;
2022-03-31 14:40:13 -04:00
TempVarExpr . ParserPtr = WorkData . AST . Get ( ) ;
2021-07-29 14:29:52 -04:00
FindOrAddRegister ( & TempVarExpr , WorkData , true ) ;
}
}
}
}
2021-07-27 14:04:39 -04:00
// now that we have determined the needed memory, let's
// setup properties as needed as well as property paths
TArray < ERigVMMemoryType > MemoryTypes ;
MemoryTypes . Add ( ERigVMMemoryType : : Work ) ;
MemoryTypes . Add ( ERigVMMemoryType : : Literal ) ;
MemoryTypes . Add ( ERigVMMemoryType : : Debug ) ;
for ( ERigVMMemoryType MemoryType : MemoryTypes )
{
2022-05-31 04:27:20 -04:00
UPackage * Package = InGraphs [ 0 ] - > GetOutermost ( ) ;
2021-08-18 06:18:21 -04:00
2021-07-28 03:35:30 -04:00
TArray < FRigVMPropertyDescription > * Properties = WorkData . PropertyDescriptions . Find ( MemoryType ) ;
2021-07-27 14:04:39 -04:00
if ( Properties = = nullptr )
{
2021-08-18 06:18:21 -04:00
URigVMMemoryStorageGeneratorClass : : RemoveStorageClass ( Package , MemoryType ) ;
2021-07-27 14:04:39 -04:00
continue ;
}
2021-08-03 08:50:47 -04:00
URigVMMemoryStorageGeneratorClass : : CreateStorageClass ( Package , MemoryType , * Properties ) ;
2021-07-27 14:04:39 -04:00
}
2021-08-03 08:50:47 -04:00
WorkData . VM - > ClearMemory ( ) ;
2020-01-22 17:58:55 -05:00
WorkData . bSetupMemory = false ;
WorkData . ExprComplete . Reset ( ) ;
2022-03-31 14:40:13 -04:00
for ( FRigVMExprAST * RootExpr : * WorkData . AST )
2020-01-22 17:58:55 -05:00
{
TraverseExpression ( RootExpr , WorkData ) ;
}
2020-09-24 00:43:27 -04:00
if ( WorkData . VM - > GetByteCode ( ) . GetInstructions ( ) . Num ( ) = = 0 )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
WorkData . VM - > GetByteCode ( ) . AddExitOp ( ) ;
2020-01-22 17:58:55 -05:00
}
2020-10-15 13:40:12 -04:00
WorkData . VM - > GetByteCode ( ) . AlignByteCode ( ) ;
2021-05-14 02:36:03 -04:00
// setup debug registers after all other registers have been created
if ( Settings . EnablePinWatches )
2021-04-29 05:02:50 -04:00
{
2021-07-29 14:29:52 -04:00
for ( URigVMPin * WatchedPin : WorkData . WatchedPins )
{
2022-03-31 14:40:13 -04:00
MarkDebugWatch ( true , WatchedPin , WorkData . VM , WorkData . PinPathToOperand , WorkData . AST ) ;
2021-07-29 14:29:52 -04:00
}
2021-04-29 05:02:50 -04:00
}
2021-07-29 14:29:52 -04:00
// now that we have determined the needed memory, let's
// update the property paths once more
for ( ERigVMMemoryType MemoryType : MemoryTypes )
{
const TArray < FRigVMPropertyPathDescription > * Descriptions = WorkData . PropertyPathDescriptions . Find ( MemoryType ) ;
if ( URigVMMemoryStorage * MemoryStorageObject = WorkData . VM - > GetMemoryByType ( MemoryType ) )
{
if ( URigVMMemoryStorageGeneratorClass * Class = Cast < URigVMMemoryStorageGeneratorClass > ( MemoryStorageObject - > GetClass ( ) ) )
{
if ( Descriptions )
{
Class - > PropertyPathDescriptions = * Descriptions ;
}
else
{
Class - > PropertyPathDescriptions . Reset ( ) ;
}
Class - > RefreshPropertyPaths ( ) ;
}
}
}
if ( const TArray < FRigVMPropertyPathDescription > * Descriptions = WorkData . PropertyPathDescriptions . Find ( ERigVMMemoryType : : External ) )
{
WorkData . VM - > ExternalPropertyPathDescriptions = * Descriptions ;
}
2020-01-22 17:58:55 -05:00
return true ;
}
void URigVMCompiler : : TraverseExpression ( const FRigVMExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
2020-09-24 00:43:27 -04:00
if ( WorkData . ExprToSkip . Contains ( InExpr ) )
{
return ;
}
2020-01-22 17:58:55 -05:00
if ( WorkData . ExprComplete . Contains ( InExpr ) )
{
return ;
}
WorkData . ExprComplete . Add ( InExpr , true ) ;
2021-05-11 17:13:58 -04:00
InitializeLocalVariables ( InExpr , WorkData ) ;
2020-01-22 17:58:55 -05:00
switch ( InExpr - > GetType ( ) )
{
case FRigVMExprAST : : EType : : Block :
{
TraverseBlock ( InExpr - > To < FRigVMBlockExprAST > ( ) , WorkData ) ;
break ;
}
case FRigVMExprAST : : EType : : Entry :
{
TraverseEntry ( InExpr - > To < FRigVMEntryExprAST > ( ) , WorkData ) ;
break ;
}
case FRigVMExprAST : : EType : : CallExtern :
{
2020-09-24 00:43:27 -04:00
const FRigVMCallExternExprAST * CallExternExpr = InExpr - > To < FRigVMCallExternExprAST > ( ) ;
2020-12-02 10:59:58 -04:00
if ( URigVMUnitNode * UnitNode = Cast < URigVMUnitNode > ( CallExternExpr - > GetNode ( ) ) )
2020-09-24 00:43:27 -04:00
{
2020-12-02 10:59:58 -04:00
if ( UnitNode - > IsLoopNode ( ) )
2020-09-24 00:43:27 -04:00
{
TraverseForLoop ( CallExternExpr , WorkData ) ;
break ;
}
}
TraverseCallExtern ( CallExternExpr , WorkData ) ;
2020-01-22 17:58:55 -05:00
break ;
}
case FRigVMExprAST : : EType : : NoOp :
{
TraverseNoOp ( InExpr - > To < FRigVMNoOpExprAST > ( ) , WorkData ) ;
break ;
}
case FRigVMExprAST : : EType : : Var :
{
TraverseVar ( InExpr - > To < FRigVMVarExprAST > ( ) , WorkData ) ;
break ;
}
case FRigVMExprAST : : EType : : Literal :
{
TraverseLiteral ( InExpr - > To < FRigVMLiteralExprAST > ( ) , WorkData ) ;
break ;
}
2020-10-26 06:51:31 -04:00
case FRigVMExprAST : : EType : : ExternalVar :
{
TraverseExternalVar ( InExpr - > To < FRigVMExternalVarExprAST > ( ) , WorkData ) ;
break ;
}
2020-01-22 17:58:55 -05:00
case FRigVMExprAST : : EType : : Assign :
{
TraverseAssign ( InExpr - > To < FRigVMAssignExprAST > ( ) , WorkData ) ;
break ;
}
case FRigVMExprAST : : EType : : Copy :
{
TraverseCopy ( InExpr - > To < FRigVMCopyExprAST > ( ) , WorkData ) ;
break ;
}
case FRigVMExprAST : : EType : : CachedValue :
{
TraverseCachedValue ( InExpr - > To < FRigVMCachedValueExprAST > ( ) , WorkData ) ;
break ;
}
case FRigVMExprAST : : EType : : Exit :
{
TraverseExit ( InExpr - > To < FRigVMExitExprAST > ( ) , WorkData ) ;
break ;
}
2020-09-24 00:43:27 -04:00
case FRigVMExprAST : : EType : : Branch :
{
TraverseBranch ( InExpr - > To < FRigVMBranchExprAST > ( ) , WorkData ) ;
break ;
}
case FRigVMExprAST : : EType : : If :
{
TraverseIf ( InExpr - > To < FRigVMIfExprAST > ( ) , WorkData ) ;
break ;
}
case FRigVMExprAST : : EType : : Select :
{
TraverseSelect ( InExpr - > To < FRigVMSelectExprAST > ( ) , WorkData ) ;
break ;
}
2021-08-18 06:18:21 -04:00
case FRigVMExprAST : : EType : : Array :
{
TraverseArray ( InExpr - > To < FRigVMArrayExprAST > ( ) , WorkData ) ;
break ;
}
2022-06-01 05:56:08 -04:00
case FRigVMExprAST : : EType : : InvokeEntry :
{
TraverseInvokeEntry ( InExpr - > To < FRigVMInvokeEntryExprAST > ( ) , WorkData ) ;
break ;
}
2020-01-22 17:58:55 -05:00
default :
{
ensure ( false ) ;
break ;
}
}
}
void URigVMCompiler : : TraverseChildren ( const FRigVMExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
for ( FRigVMExprAST * ChildExpr : * InExpr )
{
TraverseExpression ( ChildExpr , WorkData ) ;
}
}
void URigVMCompiler : : TraverseBlock ( const FRigVMBlockExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
2020-09-24 00:43:27 -04:00
if ( InExpr - > IsObsolete ( ) )
2020-01-22 17:58:55 -05:00
{
return ;
}
TraverseChildren ( InExpr , WorkData ) ;
}
void URigVMCompiler : : TraverseEntry ( const FRigVMEntryExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
2020-12-02 10:59:58 -04:00
URigVMUnitNode * UnitNode = Cast < URigVMUnitNode > ( InExpr - > GetNode ( ) ) ;
2021-09-08 07:57:30 -04:00
if ( ! ValidateNode ( UnitNode ) )
{
return ;
}
2020-01-22 17:58:55 -05:00
if ( WorkData . bSetupMemory )
{
2020-12-02 10:59:58 -04:00
TSharedPtr < FStructOnScope > DefaultStruct = UnitNode - > ConstructStructInstance ( ) ;
2020-01-22 17:58:55 -05:00
WorkData . DefaultStructs . Add ( DefaultStruct ) ;
TraverseChildren ( InExpr , WorkData ) ;
WorkData . DefaultStructs . Pop ( ) ;
}
else
{
TArray < FRigVMOperand > Operands ;
for ( FRigVMExprAST * ChildExpr : * InExpr )
{
if ( ChildExpr - > IsA ( FRigVMExprAST : : EType : : Var ) )
{
2021-08-18 06:18:21 -04:00
Operands . Add ( WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( ChildExpr ) ) ) ;
2020-01-22 17:58:55 -05:00
}
else
{
break ;
}
}
// setup the instruction
2020-12-02 10:59:58 -04:00
int32 FunctionIndex = WorkData . VM - > AddRigVMFunction ( UnitNode - > GetScriptStruct ( ) , UnitNode - > GetMethodName ( ) ) ;
2020-09-24 00:43:27 -04:00
WorkData . VM - > GetByteCode ( ) . AddExecuteOp ( FunctionIndex , Operands ) ;
int32 EntryInstructionIndex = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
2020-12-02 10:59:58 -04:00
FName Entryname = UnitNode - > GetEventName ( ) ;
2020-09-24 00:43:27 -04:00
if ( WorkData . VM - > GetByteCode ( ) . FindEntryIndex ( Entryname ) = = INDEX_NONE )
{
FRigVMByteCodeEntry Entry ;
Entry . Name = Entryname ;
Entry . InstructionIndex = EntryInstructionIndex ;
WorkData . VM - > GetByteCode ( ) . Entries . Add ( Entry ) ;
}
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
const FRigVMCallstack Callstack = InExpr - > GetProxy ( ) . GetCallstack ( ) ;
WorkData . VM - > GetByteCode ( ) . SetSubject ( EntryInstructionIndex , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2020-09-24 00:43:27 -04:00
}
2020-01-22 17:58:55 -05:00
TraverseChildren ( InExpr , WorkData ) ;
}
}
2020-09-24 00:43:27 -04:00
int32 URigVMCompiler : : TraverseCallExtern ( const FRigVMCallExternExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
2020-01-22 17:58:55 -05:00
{
2020-12-02 10:59:58 -04:00
URigVMUnitNode * UnitNode = Cast < URigVMUnitNode > ( InExpr - > GetNode ( ) ) ;
2021-09-08 07:57:30 -04:00
if ( ! ValidateNode ( UnitNode ) )
{
return INDEX_NONE ;
}
2020-01-22 17:58:55 -05:00
2022-03-31 14:40:13 -04:00
if ( UnitNode - > GetScriptStruct ( ) = = nullptr )
{
return INDEX_NONE ;
}
2020-09-24 00:43:27 -04:00
int32 InstructionIndex = INDEX_NONE ;
2020-01-22 17:58:55 -05:00
if ( WorkData . bSetupMemory )
{
2020-12-02 10:59:58 -04:00
TSharedPtr < FStructOnScope > DefaultStruct = UnitNode - > ConstructStructInstance ( ) ;
2020-01-22 17:58:55 -05:00
WorkData . DefaultStructs . Add ( DefaultStruct ) ;
TraverseChildren ( InExpr , WorkData ) ;
WorkData . DefaultStructs . Pop ( ) ;
}
else
{
TArray < FRigVMOperand > Operands ;
for ( FRigVMExprAST * ChildExpr : * InExpr )
{
if ( ChildExpr - > GetType ( ) = = FRigVMExprAST : : EType : : CachedValue )
{
2021-08-18 06:18:21 -04:00
Operands . Add ( WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( ChildExpr - > To < FRigVMCachedValueExprAST > ( ) - > GetVarExpr ( ) ) ) ) ;
2020-01-22 17:58:55 -05:00
}
else if ( ChildExpr - > IsA ( FRigVMExprAST : : EType : : Var ) )
{
2021-08-18 06:18:21 -04:00
Operands . Add ( WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( ChildExpr - > To < FRigVMVarExprAST > ( ) ) ) ) ;
2020-01-22 17:58:55 -05:00
}
else
{
break ;
}
}
TraverseChildren ( InExpr , WorkData ) ;
// setup the instruction
2020-12-02 10:59:58 -04:00
int32 FunctionIndex = WorkData . VM - > AddRigVMFunction ( UnitNode - > GetScriptStruct ( ) , UnitNode - > GetMethodName ( ) ) ;
2020-09-24 00:43:27 -04:00
WorkData . VM - > GetByteCode ( ) . AddExecuteOp ( FunctionIndex , Operands ) ;
InstructionIndex = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
2021-10-12 21:21:22 -04:00
# if WITH_EDITORONLY_DATA
TArray < FRigVMOperand > InputsOperands , OutputOperands ;
for ( const URigVMPin * InputPin : UnitNode - > GetPins ( ) )
{
if ( InputPin - > IsExecuteContext ( ) )
{
continue ;
}
const FRigVMOperand & Operand = Operands [ InputPin - > GetPinIndex ( ) ] ;
if ( InputPin - > GetDirection ( ) = = ERigVMPinDirection : : Output | | InputPin - > GetDirection ( ) = = ERigVMPinDirection : : IO )
{
OutputOperands . Add ( Operand ) ;
}
if ( InputPin - > GetDirection ( ) ! = ERigVMPinDirection : : Input & & InputPin - > GetDirection ( ) ! = ERigVMPinDirection : : IO )
{
continue ;
}
InputsOperands . Add ( Operand ) ;
}
WorkData . VM - > GetByteCode ( ) . SetOperandsForInstruction (
InstructionIndex ,
FRigVMOperandArray ( InputsOperands . GetData ( ) , InputsOperands . Num ( ) ) ,
FRigVMOperandArray ( OutputOperands . GetData ( ) , OutputOperands . Num ( ) ) ) ;
# endif
2020-09-24 00:43:27 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
const FRigVMCallstack Callstack = InExpr - > GetProxy ( ) . GetCallstack ( ) ;
WorkData . VM - > GetByteCode ( ) . SetSubject ( InstructionIndex , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2020-09-24 00:43:27 -04:00
}
2020-01-22 17:58:55 -05:00
}
2020-09-24 00:43:27 -04:00
return InstructionIndex ;
}
void URigVMCompiler : : TraverseForLoop ( const FRigVMCallExternExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
if ( WorkData . bSetupMemory )
{
TraverseCallExtern ( InExpr , WorkData ) ;
return ;
}
2020-12-02 10:59:58 -04:00
URigVMUnitNode * UnitNode = Cast < URigVMUnitNode > ( InExpr - > GetNode ( ) ) ;
2021-09-08 07:57:30 -04:00
if ( ! ValidateNode ( UnitNode ) )
{
return ;
}
2021-05-11 17:13:58 -04:00
const FRigVMCallstack Callstack = InExpr - > GetProxy ( ) . GetCallstack ( ) ;
2020-09-24 00:43:27 -04:00
const FRigVMVarExprAST * CompletedExpr = InExpr - > FindVarWithPinName ( FRigVMStruct : : ForLoopCompletedPinName ) ;
check ( CompletedExpr ) ;
const FRigVMVarExprAST * ExecuteExpr = InExpr - > FindVarWithPinName ( FRigVMStruct : : ExecuteContextName ) ;
check ( ExecuteExpr ) ;
WorkData . ExprToSkip . AddUnique ( CompletedExpr ) ;
WorkData . ExprToSkip . AddUnique ( ExecuteExpr ) ;
// set the index to 0
const FRigVMVarExprAST * IndexExpr = InExpr - > FindVarWithPinName ( FRigVMStruct : : ForLoopIndexPinName ) ;
check ( IndexExpr ) ;
FRigVMOperand IndexOperand = WorkData . ExprToOperand . FindChecked ( IndexExpr ) ;
WorkData . VM - > GetByteCode ( ) . AddZeroOp ( IndexOperand ) ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
// call the for loop compute
int32 ForLoopInstructionIndex = TraverseCallExtern ( InExpr , WorkData ) ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( ForLoopInstructionIndex , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
// set up the jump forward (jump out of the loop)
const FRigVMVarExprAST * ContinueLoopExpr = InExpr - > FindVarWithPinName ( FRigVMStruct : : ForLoopContinuePinName ) ;
check ( ContinueLoopExpr ) ;
FRigVMOperand ContinueLoopOperand = WorkData . ExprToOperand . FindChecked ( ContinueLoopExpr ) ;
uint64 JumpToEndByte = WorkData . VM - > GetByteCode ( ) . AddJumpIfOp ( ERigVMOpCode : : JumpForwardIf , 0 , ContinueLoopOperand , false ) ;
int32 JumpToEndInstruction = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
// begin the loop's block
const FRigVMVarExprAST * CountExpr = InExpr - > FindVarWithPinName ( FRigVMStruct : : ForLoopCountPinName ) ;
check ( CountExpr ) ;
FRigVMOperand CountOperand = WorkData . ExprToOperand . FindChecked ( CountExpr ) ;
WorkData . VM - > GetByteCode ( ) . AddBeginBlockOp ( CountOperand , IndexOperand ) ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
// traverse the body of the loop
WorkData . ExprToSkip . Remove ( ExecuteExpr ) ;
TraverseExpression ( ExecuteExpr , WorkData ) ;
// end the loop's block
WorkData . VM - > GetByteCode ( ) . AddEndBlockOp ( ) ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
// increment the index
WorkData . VM - > GetByteCode ( ) . AddIncrementOp ( IndexOperand ) ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
// jump to the beginning of the loop
int32 JumpToStartInstruction = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) ;
WorkData . VM - > GetByteCode ( ) . AddJumpOp ( ERigVMOpCode : : JumpBackward , JumpToStartInstruction - ForLoopInstructionIndex ) ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
// update the jump operator with the right address
int32 InstructionsToEnd = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - JumpToEndInstruction ;
WorkData . VM - > GetByteCode ( ) . GetOpAt < FRigVMJumpIfOp > ( JumpToEndByte ) . InstructionIndex = InstructionsToEnd ;
// now traverse everything else connected to the completed pin
WorkData . ExprToSkip . Remove ( CompletedExpr ) ;
TraverseExpression ( CompletedExpr , WorkData ) ;
2020-01-22 17:58:55 -05:00
}
void URigVMCompiler : : TraverseNoOp ( const FRigVMNoOpExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
TraverseChildren ( InExpr , WorkData ) ;
}
void URigVMCompiler : : TraverseVar ( const FRigVMVarExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
TraverseChildren ( InExpr , WorkData ) ;
if ( WorkData . bSetupMemory )
{
FindOrAddRegister ( InExpr , WorkData ) ;
}
}
void URigVMCompiler : : TraverseLiteral ( const FRigVMVarExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
TraverseVar ( InExpr , WorkData ) ;
}
2020-10-26 06:51:31 -04:00
void URigVMCompiler : : TraverseExternalVar ( const FRigVMExternalVarExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
TraverseVar ( InExpr , WorkData ) ;
}
2020-01-22 17:58:55 -05:00
void URigVMCompiler : : TraverseAssign ( const FRigVMAssignExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
TraverseChildren ( InExpr , WorkData ) ;
ensure ( InExpr - > NumChildren ( ) > 0 ) ;
const FRigVMVarExprAST * SourceExpr = nullptr ;
const FRigVMExprAST * ChildExpr = InExpr - > ChildAt ( 0 ) ;
if ( ChildExpr - > IsA ( FRigVMExprAST : : EType : : Var ) )
{
SourceExpr = ChildExpr - > To < FRigVMVarExprAST > ( ) ;
}
else if ( ChildExpr - > GetType ( ) = = FRigVMExprAST : : EType : : CachedValue )
{
SourceExpr = ChildExpr - > To < FRigVMCachedValueExprAST > ( ) - > GetVarExpr ( ) ;
}
else if ( ChildExpr - > GetType ( ) = = FRigVMExprAST : : EType : : NoOp )
{
ensure ( ChildExpr - > NumChildren ( ) > 0 ) ;
for ( FRigVMExprAST * GrandChild : * ChildExpr )
{
if ( GrandChild - > IsA ( FRigVMExprAST : : EType : : Var ) )
{
const FRigVMVarExprAST * VarExpr = GrandChild - > To < FRigVMVarExprAST > ( ) ;
2020-09-24 00:43:27 -04:00
if ( VarExpr - > GetPin ( ) - > GetName ( ) = = TEXT ( " Value " ) | |
VarExpr - > GetPin ( ) - > GetName ( ) = = TEXT ( " EnumIndex " ) )
2020-01-22 17:58:55 -05:00
{
SourceExpr = VarExpr ;
break ;
}
}
}
check ( SourceExpr ) ;
}
else
{
checkNoEntry ( ) ;
}
2021-08-18 06:18:21 -04:00
FRigVMOperand Source = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( SourceExpr ) ) ;
2020-01-22 17:58:55 -05:00
2021-07-27 14:04:39 -04:00
if ( ! WorkData . bSetupMemory )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
const FRigVMVarExprAST * TargetExpr = InExpr - > GetFirstParentOfType ( FRigVMVarExprAST : : EType : : Var ) - > To < FRigVMVarExprAST > ( ) ;
2021-08-18 06:18:21 -04:00
TargetExpr = GetSourceVarExpr ( TargetExpr ) ;
2020-01-22 17:58:55 -05:00
FRigVMOperand Target = WorkData . ExprToOperand . FindChecked ( TargetExpr ) ;
2021-08-18 06:18:21 -04:00
if ( Target = = Source )
{
return ;
}
2022-03-31 14:40:13 -04:00
2020-01-22 17:58:55 -05:00
// if this is a copy - we should check if operands need offsets
if ( InExpr - > GetType ( ) = = FRigVMExprAST : : EType : : Copy )
{
struct Local
{
2022-03-31 14:40:13 -04:00
static void SetupRegisterOffset ( URigVM * VM , const FRigVMASTLinkDescription & InLink , URigVMPin * Pin ,
FRigVMOperand & Operand , const FRigVMVarExprAST * VarExpr , bool bSource , FRigVMCompilerWorkData & WorkData )
2020-01-22 17:58:55 -05:00
{
2022-03-31 14:40:13 -04:00
const bool bHasTargetSegmentPath = ! bSource & & ! InLink . SegmentPath . IsEmpty ( ) ;
2020-01-22 17:58:55 -05:00
URigVMPin * RootPin = Pin - > GetRootPin ( ) ;
2022-03-31 14:40:13 -04:00
if ( Pin = = RootPin & & ! bHasTargetSegmentPath )
2020-01-22 17:58:55 -05:00
{
return ;
}
2022-03-31 14:40:13 -04:00
FString SegmentPath = Pin - > GetSegmentPath ( false ) ;
if ( bHasTargetSegmentPath )
2020-09-24 00:43:27 -04:00
{
2022-03-31 14:40:13 -04:00
if ( SegmentPath . IsEmpty ( ) )
2020-09-24 00:43:27 -04:00
{
2022-03-31 14:40:13 -04:00
SegmentPath = InLink . SegmentPath ;
2022-03-31 14:39:59 -04:00
}
else
2022-03-31 14:40:13 -04:00
{
SegmentPath = URigVMPin : : JoinPinPath ( SegmentPath , InLink . SegmentPath ) ;
2022-03-31 14:39:59 -04:00
}
}
2022-03-31 14:40:13 -04:00
// for select nodes we create a register for each case (since the cases are fixed in size)
// thus we do not need to setup a registeroffset for the array element.
if ( URigVMSelectNode * SelectNode = Cast < URigVMSelectNode > ( RootPin - > GetNode ( ) ) )
{
if ( RootPin - > GetName ( ) = = URigVMSelectNode : : ValueName )
{
if ( Pin - > GetParentPin ( ) = = RootPin )
{
return ;
}
// if the pin is a sub pin of a case of the select (for example: Values.0.Translation)
// we'll need to re-adjust the root pin to the case pin (for example: Values.0)
TArray < FString > SegmentPathPaths ;
if ( ensure ( URigVMPin : : SplitPinPath ( SegmentPath , SegmentPathPaths ) ) )
{
RootPin = RootPin - > FindSubPin ( SegmentPathPaths [ 0 ] ) ;
SegmentPathPaths . RemoveAt ( 0 ) ;
ensure ( SegmentPathPaths . Num ( ) > 0 ) ;
SegmentPath = URigVMPin : : JoinPinPath ( SegmentPathPaths ) ;
}
else
{
return ;
}
}
}
2022-03-31 14:39:59 -04:00
2021-07-29 14:29:52 -04:00
const int32 PropertyPathIndex = WorkData . FindOrAddPropertyPath ( Operand , RootPin - > GetCPPType ( ) , SegmentPath ) ;
2021-07-27 14:04:39 -04:00
Operand = FRigVMOperand ( Operand . GetMemoryType ( ) , Operand . GetRegisterIndex ( ) , PropertyPathIndex ) ;
2020-01-22 17:58:55 -05:00
}
} ;
2022-03-31 14:40:13 -04:00
const FRigVMASTLinkDescription & Link = InExpr - > GetLink ( ) ;
Local : : SetupRegisterOffset ( WorkData . VM , Link , InExpr - > GetSourcePin ( ) , Source , SourceExpr , true , WorkData ) ;
Local : : SetupRegisterOffset ( WorkData . VM , Link , InExpr - > GetTargetPin ( ) , Target , TargetExpr , false , WorkData ) ;
2020-01-22 17:58:55 -05:00
}
2021-08-18 06:18:21 -04:00
FRigVMCopyOp CopyOp = WorkData . VM - > GetCopyOpForOperands ( Source , Target ) ;
if ( CopyOp . IsValid ( ) )
2020-09-24 00:43:27 -04:00
{
2022-03-31 14:40:13 -04:00
AddCopyOperator ( CopyOp , InExpr , SourceExpr , TargetExpr , WorkData ) ;
2020-09-24 00:43:27 -04:00
}
2020-01-22 17:58:55 -05:00
}
}
void URigVMCompiler : : TraverseCopy ( const FRigVMCopyExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
TraverseAssign ( InExpr - > To < FRigVMAssignExprAST > ( ) , WorkData ) ;
}
void URigVMCompiler : : TraverseCachedValue ( const FRigVMCachedValueExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
TraverseChildren ( InExpr , WorkData ) ;
}
void URigVMCompiler : : TraverseExit ( const FRigVMExitExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
ensure ( InExpr - > NumChildren ( ) = = 0 ) ;
if ( ! WorkData . bSetupMemory )
{
2020-09-24 00:43:27 -04:00
WorkData . VM - > GetByteCode ( ) . AddExitOp ( ) ;
}
}
void URigVMCompiler : : TraverseBranch ( const FRigVMBranchExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
ensure ( InExpr - > NumChildren ( ) = = 4 ) ;
if ( WorkData . bSetupMemory )
{
TraverseChildren ( InExpr , WorkData ) ;
return ;
}
URigVMBranchNode * BranchNode = Cast < URigVMBranchNode > ( InExpr - > GetNode ( ) ) ;
2021-05-11 17:13:58 -04:00
const FRigVMCallstack Callstack = InExpr - > GetProxy ( ) . GetCallstack ( ) ;
2020-09-24 00:43:27 -04:00
const FRigVMVarExprAST * ExecuteContextExpr = InExpr - > ChildAt < FRigVMVarExprAST > ( 0 ) ;
const FRigVMVarExprAST * ConditionExpr = InExpr - > ChildAt < FRigVMVarExprAST > ( 1 ) ;
const FRigVMVarExprAST * TrueExpr = InExpr - > ChildAt < FRigVMVarExprAST > ( 2 ) ;
const FRigVMVarExprAST * FalseExpr = InExpr - > ChildAt < FRigVMVarExprAST > ( 3 ) ;
// traverse the condition first
TraverseExpression ( ConditionExpr , WorkData ) ;
if ( ConditionExpr - > IsA ( FRigVMExprAST : : CachedValue ) )
{
ConditionExpr = ConditionExpr - > To < FRigVMCachedValueExprAST > ( ) - > GetVarExpr ( ) ;
}
FRigVMOperand & ConditionOperand = WorkData . ExprToOperand . FindChecked ( ConditionExpr ) ;
// setup the first jump
uint64 JumpToFalseByte = WorkData . VM - > GetByteCode ( ) . AddJumpIfOp ( ERigVMOpCode : : JumpForwardIf , 1 , ConditionOperand , false ) ;
int32 JumpToFalseInstruction = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2020-09-24 00:43:27 -04:00
}
// traverse the true case
TraverseExpression ( TrueExpr , WorkData ) ;
uint64 JumpToEndByte = WorkData . VM - > GetByteCode ( ) . AddJumpOp ( ERigVMOpCode : : JumpForward , 1 ) ;
int32 JumpToEndInstruction = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
// correct the jump to false instruction index
int32 NumInstructionsInTrueCase = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - JumpToFalseInstruction ;
WorkData . VM - > GetByteCode ( ) . GetOpAt < FRigVMJumpIfOp > ( JumpToFalseByte ) . InstructionIndex = NumInstructionsInTrueCase ;
// traverse the false case
TraverseExpression ( FalseExpr , WorkData ) ;
// correct the jump to end instruction index
int32 NumInstructionsInFalseCase = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - JumpToEndInstruction ;
WorkData . VM - > GetByteCode ( ) . GetOpAt < FRigVMJumpOp > ( JumpToEndByte ) . InstructionIndex = NumInstructionsInFalseCase ;
}
void URigVMCompiler : : TraverseIf ( const FRigVMIfExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
ensure ( InExpr - > NumChildren ( ) = = 4 ) ;
if ( WorkData . bSetupMemory )
{
TraverseChildren ( InExpr , WorkData ) ;
return ;
}
URigVMIfNode * IfNode = Cast < URigVMIfNode > ( InExpr - > GetNode ( ) ) ;
2021-09-08 07:57:30 -04:00
if ( ! ValidateNode ( IfNode ) )
{
return ;
}
2021-05-11 17:13:58 -04:00
const FRigVMCallstack Callstack = InExpr - > GetProxy ( ) . GetCallstack ( ) ;
2020-09-24 00:43:27 -04:00
const FRigVMVarExprAST * ConditionExpr = InExpr - > ChildAt < FRigVMVarExprAST > ( 0 ) ;
const FRigVMVarExprAST * TrueExpr = InExpr - > ChildAt < FRigVMVarExprAST > ( 1 ) ;
const FRigVMVarExprAST * FalseExpr = InExpr - > ChildAt < FRigVMVarExprAST > ( 2 ) ;
const FRigVMVarExprAST * ResultExpr = InExpr - > ChildAt < FRigVMVarExprAST > ( 3 ) ;
// traverse the condition first
TraverseExpression ( ConditionExpr , WorkData ) ;
if ( ConditionExpr - > IsA ( FRigVMExprAST : : CachedValue ) )
{
ConditionExpr = ConditionExpr - > To < FRigVMCachedValueExprAST > ( ) - > GetVarExpr ( ) ;
}
FRigVMOperand & ConditionOperand = WorkData . ExprToOperand . FindChecked ( ConditionExpr ) ;
FRigVMOperand & ResultOperand = WorkData . ExprToOperand . FindChecked ( ResultExpr ) ;
// setup the first jump
uint64 JumpToFalseByte = WorkData . VM - > GetByteCode ( ) . AddJumpIfOp ( ERigVMOpCode : : JumpForwardIf , 1 , ConditionOperand , false ) ;
int32 JumpToFalseInstruction = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2020-09-24 00:43:27 -04:00
}
// traverse the true case
TraverseExpression ( TrueExpr , WorkData ) ;
if ( TrueExpr - > IsA ( FRigVMExprAST : : CachedValue ) )
{
TrueExpr = TrueExpr - > To < FRigVMCachedValueExprAST > ( ) - > GetVarExpr ( ) ;
}
FRigVMOperand & TrueOperand = WorkData . ExprToOperand . FindChecked ( TrueExpr ) ;
2021-05-17 12:35:41 -04:00
WorkData . VM - > GetByteCode ( ) . AddCopyOp ( WorkData . VM - > GetCopyOpForOperands ( TrueOperand , ResultOperand ) ) ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
uint64 JumpToEndByte = WorkData . VM - > GetByteCode ( ) . AddJumpOp ( ERigVMOpCode : : JumpForward , 1 ) ;
int32 JumpToEndInstruction = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
// correct the jump to false instruction index
int32 NumInstructionsInTrueCase = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - JumpToFalseInstruction ;
WorkData . VM - > GetByteCode ( ) . GetOpAt < FRigVMJumpIfOp > ( JumpToFalseByte ) . InstructionIndex = NumInstructionsInTrueCase ;
// traverse the false case
TraverseExpression ( FalseExpr , WorkData ) ;
if ( FalseExpr - > IsA ( FRigVMExprAST : : CachedValue ) )
{
FalseExpr = FalseExpr - > To < FRigVMCachedValueExprAST > ( ) - > GetVarExpr ( ) ;
}
FRigVMOperand & FalseOperand = WorkData . ExprToOperand . FindChecked ( FalseExpr ) ;
2021-05-17 12:35:41 -04:00
WorkData . VM - > GetByteCode ( ) . AddCopyOp ( WorkData . VM - > GetCopyOpForOperands ( FalseOperand , ResultOperand ) ) ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
// correct the jump to end instruction index
int32 NumInstructionsInFalseCase = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - JumpToEndInstruction ;
WorkData . VM - > GetByteCode ( ) . GetOpAt < FRigVMJumpOp > ( JumpToEndByte ) . InstructionIndex = NumInstructionsInFalseCase ;
}
void URigVMCompiler : : TraverseSelect ( const FRigVMSelectExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
URigVMSelectNode * SelectNode = Cast < URigVMSelectNode > ( InExpr - > GetNode ( ) ) ;
2021-09-08 07:57:30 -04:00
if ( ! ValidateNode ( SelectNode ) )
{
return ;
}
2021-05-11 17:13:58 -04:00
const FRigVMCallstack Callstack = InExpr - > GetProxy ( ) . GetCallstack ( ) ;
2021-03-19 06:35:50 -04:00
2020-09-24 00:43:27 -04:00
int32 NumCases = SelectNode - > FindPin ( URigVMSelectNode : : ValueName ) - > GetArraySize ( ) ;
if ( WorkData . bSetupMemory )
{
TraverseChildren ( InExpr , WorkData ) ;
// setup literals for each index (we don't need zero)
for ( int32 CaseIndex = 1 ; CaseIndex < NumCases ; CaseIndex + + )
{
if ( ! WorkData . IntegerLiterals . Contains ( CaseIndex ) )
{
FName LiteralName = * FString : : FromInt ( CaseIndex ) ;
2021-07-27 14:04:39 -04:00
const FString DefaultValue = FString : : FromInt ( CaseIndex ) ;
FRigVMOperand Operand = WorkData . AddProperty (
ERigVMMemoryType : : Literal ,
LiteralName ,
TEXT ( " int32 " ) ,
nullptr ,
DefaultValue ) ;
2020-09-24 00:43:27 -04:00
WorkData . IntegerLiterals . Add ( CaseIndex , Operand ) ;
}
}
2020-12-04 11:37:54 -04:00
if ( ! WorkData . ComparisonOperand . IsValid ( ) )
2020-09-24 00:43:27 -04:00
{
2021-07-27 14:04:39 -04:00
WorkData . ComparisonOperand = WorkData . AddProperty (
ERigVMMemoryType : : Work ,
FName ( TEXT ( " IntEquals " ) ) ,
TEXT ( " bool " ) ,
nullptr ,
TEXT ( " false " ) ) ;
2020-09-24 00:43:27 -04:00
}
return ;
}
const FRigVMVarExprAST * IndexExpr = InExpr - > ChildAt < FRigVMVarExprAST > ( 0 ) ;
TArray < const FRigVMVarExprAST * > CaseExpressions ;
for ( int32 CaseIndex = 0 ; CaseIndex < NumCases ; CaseIndex + + )
{
CaseExpressions . Add ( InExpr - > ChildAt < FRigVMVarExprAST > ( CaseIndex + 1 ) ) ;
}
const FRigVMVarExprAST * ResultExpr = InExpr - > ChildAt < FRigVMVarExprAST > ( InExpr - > NumChildren ( ) - 1 ) ;
// traverse the condition first
TraverseExpression ( IndexExpr , WorkData ) ;
// this can happen if the optimizer doesn't remove it
if ( CaseExpressions . Num ( ) = = 0 )
{
return ;
}
if ( IndexExpr - > IsA ( FRigVMExprAST : : CachedValue ) )
{
IndexExpr = IndexExpr - > To < FRigVMCachedValueExprAST > ( ) - > GetVarExpr ( ) ;
}
FRigVMOperand & IndexOperand = WorkData . ExprToOperand . FindChecked ( IndexExpr ) ;
FRigVMOperand & ResultOperand = WorkData . ExprToOperand . FindChecked ( ResultExpr ) ;
// setup the jumps for each case
TArray < uint64 > JumpToCaseBytes ;
TArray < int32 > JumpToCaseInstructions ;
JumpToCaseBytes . Add ( 0 ) ;
JumpToCaseInstructions . Add ( 0 ) ;
for ( int32 CaseIndex = 1 ; CaseIndex < NumCases ; CaseIndex + + )
{
// compare and jump eventually
2020-12-04 11:37:54 -04:00
WorkData . VM - > GetByteCode ( ) . AddEqualsOp ( IndexOperand , WorkData . IntegerLiterals . FindChecked ( CaseIndex ) , WorkData . ComparisonOperand ) ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
2020-09-24 00:43:27 -04:00
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2020-09-24 00:43:27 -04:00
}
2020-12-04 11:37:54 -04:00
uint64 JumpByte = WorkData . VM - > GetByteCode ( ) . AddJumpIfOp ( ERigVMOpCode : : JumpForwardIf , 1 , WorkData . ComparisonOperand , true ) ;
2020-09-24 00:43:27 -04:00
int32 JumpInstruction = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
JumpToCaseBytes . Add ( JumpByte ) ;
JumpToCaseInstructions . Add ( JumpInstruction ) ;
}
TArray < uint64 > JumpToEndBytes ;
TArray < int32 > JumpToEndInstructions ;
for ( int32 CaseIndex = 0 ; CaseIndex < NumCases ; CaseIndex + + )
{
if ( CaseIndex > 0 )
{
int32 NumInstructionsInCase = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - JumpToCaseInstructions [ CaseIndex ] ;
WorkData . VM - > GetByteCode ( ) . GetOpAt < FRigVMJumpIfOp > ( JumpToCaseBytes [ CaseIndex ] ) . InstructionIndex = NumInstructionsInCase ;
}
TraverseExpression ( CaseExpressions [ CaseIndex ] , WorkData ) ;
// add copy op to copy the result
2021-08-18 06:18:21 -04:00
FRigVMOperand & CaseOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( CaseExpressions [ CaseIndex ] ) ) ;
2021-05-17 12:35:41 -04:00
WorkData . VM - > GetByteCode ( ) . AddCopyOp ( WorkData . VM - > GetCopyOpForOperands ( CaseOperand , ResultOperand ) ) ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
if ( CaseIndex < NumCases - 1 )
{
uint64 JumpByte = WorkData . VM - > GetByteCode ( ) . AddJumpOp ( ERigVMOpCode : : JumpForward , 1 ) ;
int32 JumpInstruction = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
2021-03-19 06:35:50 -04:00
if ( Settings . SetupNodeInstructionIndex )
{
2021-05-11 17:13:58 -04:00
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-03-19 06:35:50 -04:00
}
2020-09-24 00:43:27 -04:00
JumpToEndBytes . Add ( JumpByte ) ;
JumpToEndInstructions . Add ( JumpInstruction ) ;
}
}
for ( int32 CaseIndex = 0 ; CaseIndex < NumCases - 1 ; CaseIndex + + )
{
int32 NumInstructionsToEnd = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - JumpToEndInstructions [ CaseIndex ] ;
WorkData . VM - > GetByteCode ( ) . GetOpAt < FRigVMJumpOp > ( JumpToEndBytes [ CaseIndex ] ) . InstructionIndex = NumInstructionsToEnd ;
2020-01-22 17:58:55 -05:00
}
}
2021-08-18 06:18:21 -04:00
void URigVMCompiler : : TraverseArray ( const FRigVMArrayExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
URigVMArrayNode * ArrayNode = Cast < URigVMArrayNode > ( InExpr - > GetNode ( ) ) ;
2021-09-08 07:57:30 -04:00
if ( ! ValidateNode ( ArrayNode ) )
{
return ;
}
2021-08-18 06:18:21 -04:00
if ( WorkData . bSetupMemory )
{
TraverseChildren ( InExpr , WorkData ) ;
}
else
{
const FRigVMCallstack Callstack = InExpr - > GetProxy ( ) . GetCallstack ( ) ;
static const FName ExecuteName = FRigVMStruct : : ExecuteName ;
static const FName ArrayName = * URigVMArrayNode : : ArrayName ;
static const FName NumName = * URigVMArrayNode : : NumName ;
static const FName IndexName = * URigVMArrayNode : : IndexName ;
static const FName ElementName = * URigVMArrayNode : : ElementName ;
static const FName SuccessName = * URigVMArrayNode : : SuccessName ;
static const FName OtherName = * URigVMArrayNode : : OtherName ;
static const FName CloneName = * URigVMArrayNode : : CloneName ;
static const FName CountName = * URigVMArrayNode : : CountName ;
static const FName RatioName = * URigVMArrayNode : : RatioName ;
static const FName ResultName = * URigVMArrayNode : : ResultName ;
static const FName ContinueName = * URigVMArrayNode : : ContinueName ;
static const FName CompletedName = * URigVMArrayNode : : CompletedName ;
const ERigVMOpCode OpCode = ArrayNode - > GetOpCode ( ) ;
switch ( OpCode )
{
case ERigVMOpCode : : ArrayReset :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayResetOp ( ArrayOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayGetNum :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 0 ) ) ) ;
const FRigVMOperand & NumOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayGetNumOp ( ArrayOperand , NumOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArraySetNum :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
const FRigVMOperand & NumOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 2 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArraySetNumOp ( ArrayOperand , NumOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayGetAtIndex :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 0 ) ) ) ;
const FRigVMOperand & IndexOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
const FRigVMOperand & ElementOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 2 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayGetAtIndexOp ( ArrayOperand , IndexOperand , ElementOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArraySetAtIndex :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
const FRigVMOperand & IndexOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 2 ) ) ) ;
const FRigVMOperand & ElementOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 3 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArraySetAtIndexOp ( ArrayOperand , IndexOperand , ElementOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayAdd :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
const FRigVMOperand & ElementOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 2 ) ) ) ;
const FRigVMOperand & IndexOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 3 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayAddOp ( ArrayOperand , ElementOperand , IndexOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayInsert :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
const FRigVMOperand & IndexOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 2 ) ) ) ;
const FRigVMOperand & ElementOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 3 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayInsertOp ( ArrayOperand , IndexOperand , ElementOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayRemove :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
const FRigVMOperand & IndexOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 2 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayRemoveOp ( ArrayOperand , IndexOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayFind :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 0 ) ) ) ;
const FRigVMOperand & ElementOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
const FRigVMOperand & IndexOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 2 ) ) ) ;
const FRigVMOperand & SuccessOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 3 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayFindOp ( ArrayOperand , ElementOperand , IndexOperand , SuccessOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayAppend :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
const FRigVMOperand & OtherOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 2 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayAppendOp ( ArrayOperand , OtherOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayClone :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 0 ) ) ) ;
const FRigVMOperand & CloneOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayCloneOp ( ArrayOperand , CloneOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayIterator :
{
const FRigVMExprAST * ExecuteExpr = InExpr - > ChildAt ( 0 ) ;
const FRigVMExprAST * ArrayExpr = InExpr - > ChildAt ( 1 ) ;
const FRigVMExprAST * ElementExpr = InExpr - > ChildAt ( 2 ) ;
const FRigVMExprAST * IndexExpr = InExpr - > ChildAt ( 3 ) ;
const FRigVMExprAST * CountExpr = InExpr - > ChildAt ( 4 ) ;
const FRigVMExprAST * RatioExpr = InExpr - > ChildAt ( 5 ) ;
const FRigVMExprAST * ContinueExpr = InExpr - > ChildAt ( 6 ) ;
const FRigVMExprAST * CompletedExpr = InExpr - > ChildAt ( 7 ) ;
const FRigVMOperand & ExecuteOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( ExecuteExpr ) ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( ArrayExpr ) ) ;
const FRigVMOperand & ElementOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( ElementExpr ) ) ;
const FRigVMOperand & IndexOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( IndexExpr ) ) ;
const FRigVMOperand & CountOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( CountExpr ) ) ;
const FRigVMOperand & RatioOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( RatioExpr ) ) ;
const FRigVMOperand & ContinueOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( ContinueExpr ) ) ;
const FRigVMOperand & CompletedOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( CompletedExpr ) ) ;
WorkData . ExprToSkip . AddUnique ( ExecuteExpr ) ;
WorkData . ExprToSkip . AddUnique ( CompletedExpr ) ;
// traverse the input array
TraverseExpression ( ArrayExpr , WorkData ) ;
// zero the index
WorkData . VM - > GetByteCode ( ) . AddZeroOp ( IndexOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
// add the iterator
WorkData . VM - > GetByteCode ( ) . AddArrayIteratorOp ( ArrayOperand , ElementOperand , IndexOperand , CountOperand , RatioOperand , ContinueOperand ) ;
const int32 IteratorInstruction = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
// jump to the end of the loop
const uint64 JumpToEndByte = WorkData . VM - > GetByteCode ( ) . AddJumpIfOp ( ERigVMOpCode : : JumpForwardIf , 0 , ContinueOperand , false ) ;
const int32 JumpToEndInstruction = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
// begin the block
WorkData . VM - > GetByteCode ( ) . AddBeginBlockOp ( CountOperand , IndexOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
// traverse the per iteration instructions
WorkData . ExprToSkip . Remove ( ExecuteExpr ) ;
TraverseExpression ( ExecuteExpr , WorkData ) ;
// end the block
WorkData . VM - > GetByteCode ( ) . AddEndBlockOp ( ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
// increment index per loop iteration
WorkData . VM - > GetByteCode ( ) . AddIncrementOp ( IndexOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
// jump backwards instruction (to the beginning of the iterator)
const int32 JumpToStartInstruction = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) ;
WorkData . VM - > GetByteCode ( ) . AddJumpOp ( ERigVMOpCode : : JumpBackward , JumpToStartInstruction - IteratorInstruction ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
// fix up the first jump instruction
const int32 InstructionsToEnd = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - JumpToEndInstruction ;
WorkData . VM - > GetByteCode ( ) . GetOpAt < FRigVMJumpIfOp > ( JumpToEndByte ) . InstructionIndex = InstructionsToEnd ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
WorkData . ExprToSkip . Remove ( CompletedExpr ) ;
TraverseExpression ( CompletedExpr , WorkData ) ;
break ;
}
case ERigVMOpCode : : ArrayUnion :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
const FRigVMOperand & OtherOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 2 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayUnionOp ( ArrayOperand , OtherOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayDifference :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 0 ) ) ) ;
const FRigVMOperand & OtherOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
const FRigVMOperand & ResultOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 2 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayDifferenceOp ( ArrayOperand , OtherOperand , ResultOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayIntersection :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 0 ) ) ) ;
const FRigVMOperand & OtherOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
const FRigVMOperand & ResultOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 2 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayIntersectionOp ( ArrayOperand , OtherOperand , ResultOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
case ERigVMOpCode : : ArrayReverse :
{
TraverseChildren ( InExpr , WorkData ) ;
const FRigVMOperand & ArrayOperand = WorkData . ExprToOperand . FindChecked ( GetSourceVarExpr ( InExpr - > ChildAt ( 1 ) ) ) ;
WorkData . VM - > GetByteCode ( ) . AddArrayReverseOp ( ArrayOperand ) ;
if ( Settings . SetupNodeInstructionIndex )
{
WorkData . VM - > GetByteCode ( ) . SetSubject ( WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
break ;
}
default :
{
checkNoEntry ( ) ;
break ;
}
}
}
}
2022-06-01 05:56:08 -04:00
void URigVMCompiler : : TraverseInvokeEntry ( const FRigVMInvokeEntryExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
URigVMInvokeEntryNode * InvokeEntryNode = Cast < URigVMInvokeEntryNode > ( InExpr - > GetNode ( ) ) ;
if ( ! ValidateNode ( InvokeEntryNode ) )
{
return ;
}
if ( WorkData . bSetupMemory )
{
return ;
}
else
{
WorkData . VM - > GetByteCode ( ) . AddInvokeEntryOp ( InvokeEntryNode - > GetEntryName ( ) ) ;
}
}
2022-03-31 14:40:13 -04:00
void URigVMCompiler : : AddCopyOperator ( const FRigVMCopyOp & InOp , const FRigVMAssignExprAST * InAssignExpr ,
2022-06-01 05:56:08 -04:00
const FRigVMVarExprAST * InSourceExpr , const FRigVMVarExprAST * InTargetExpr , FRigVMCompilerWorkData & WorkData ,
bool bDelayCopyOperations )
2022-03-31 14:40:13 -04:00
{
if ( bDelayCopyOperations )
{
// if this is a full literal copy, let's delay it.
// to maintain the execution order we want nodes which compose a value
// to delay their reset to the default value, which happens prior to
// computing dependencies.
// so for example an external variable of FVector may need to be reset
// to a literal value prior to the rest of the composition, for example
// if there's a float link only on the Y component. the execution order
// desired is this:
//
// * Run all dependent branches
// * Copy the literal value into the variable
// * Copy the parts into the variable (like the Y component).
//
// By delaying the copy operator until right before the very first composition
// copy operator we ensure the desired execution order
if ( InOp . Target . GetRegisterOffset ( ) = = INDEX_NONE & &
InOp . Source . GetMemoryType ( ) = = ERigVMMemoryType : : Literal & &
InOp . Source . GetRegisterOffset ( ) = = INDEX_NONE )
{
if ( URigVMPin * Pin = InTargetExpr - > GetPin ( ) )
{
if ( URigVMPin * RootPin = Pin - > GetRootPin ( ) )
{
const FRigVMASTProxy RootPinProxy = InTargetExpr - > GetProxy ( ) . GetSibling ( RootPin ) ;
// if the root pin has only links on its subpins
if ( WorkData . AST - > GetSourceLinkIndices ( RootPinProxy , false ) . Num ( ) = = 0 )
{
if ( WorkData . AST - > GetSourceLinkIndices ( RootPinProxy , true ) . Num ( ) > 0 )
{
FRigVMCompilerWorkData : : FCopyOpInfo DeferredCopyOp ;
DeferredCopyOp . Op = InOp ;
DeferredCopyOp . AssignExpr = InAssignExpr ;
DeferredCopyOp . SourceExpr = InSourceExpr ;
DeferredCopyOp . TargetExpr = InTargetExpr ;
const FRigVMOperand Key ( InOp . Target . GetMemoryType ( ) , InOp . Target . GetRegisterIndex ( ) ) ;
WorkData . DeferredCopyOps . FindOrAdd ( Key ) = DeferredCopyOp ;
return ;
}
}
}
}
}
bDelayCopyOperations = false ;
}
// loop up a potentially delayed copy operation which needs to happen
// just prior to this one and inject it as well.
if ( ! bDelayCopyOperations )
{
const FRigVMOperand DeferredKey ( InOp . Target . GetMemoryType ( ) , InOp . Target . GetRegisterIndex ( ) ) ;
const FRigVMCompilerWorkData : : FCopyOpInfo * DeferredCopyOpPtr = WorkData . DeferredCopyOps . Find ( DeferredKey ) ;
if ( DeferredCopyOpPtr ! = nullptr )
{
FRigVMCompilerWorkData : : FCopyOpInfo CopyOpInfo = * DeferredCopyOpPtr ;
WorkData . DeferredCopyOps . Remove ( DeferredKey ) ;
AddCopyOperator ( CopyOpInfo , WorkData , false ) ;
}
}
WorkData . VM - > GetByteCode ( ) . AddCopyOp ( InOp ) ;
int32 InstructionIndex = WorkData . VM - > GetByteCode ( ) . GetNumInstructions ( ) - 1 ;
if ( Settings . SetupNodeInstructionIndex )
{
if ( URigVMPin * SourcePin = InAssignExpr - > GetSourcePin ( ) )
{
if ( URigVMVariableNode * VariableNode = Cast < URigVMVariableNode > ( SourcePin - > GetNode ( ) ) )
{
const FRigVMCallstack Callstack = InSourceExpr - > GetProxy ( ) . GetSibling ( VariableNode ) . GetCallstack ( ) ;
WorkData . VM - > GetByteCode ( ) . SetSubject ( InstructionIndex , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
}
if ( URigVMPin * TargetPin = InAssignExpr - > GetTargetPin ( ) )
{
if ( URigVMVariableNode * VariableNode = Cast < URigVMVariableNode > ( TargetPin - > GetNode ( ) ) )
{
const FRigVMCallstack Callstack = InTargetExpr - > GetProxy ( ) . GetSibling ( VariableNode ) . GetCallstack ( ) ;
WorkData . VM - > GetByteCode ( ) . SetSubject ( InstructionIndex , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
}
}
}
}
void URigVMCompiler : : AddCopyOperator (
const FRigVMCompilerWorkData : : FCopyOpInfo & CopyOpInfo ,
FRigVMCompilerWorkData & WorkData ,
bool bDelayCopyOperations )
{
AddCopyOperator ( CopyOpInfo . Op , CopyOpInfo . AssignExpr , CopyOpInfo . SourceExpr , CopyOpInfo . TargetExpr , WorkData , bDelayCopyOperations ) ;
}
2021-05-11 17:13:58 -04:00
void URigVMCompiler : : InitializeLocalVariables ( const FRigVMExprAST * InExpr , FRigVMCompilerWorkData & WorkData )
{
// Initialize local variables if we are entering a new graph
if ( ! WorkData . bSetupMemory )
{
FRigVMByteCode & ByteCode = WorkData . VM - > GetByteCode ( ) ;
2021-08-20 12:55:39 -04:00
const FRigVMASTProxy * Proxy = nullptr ;
2021-05-11 17:13:58 -04:00
switch ( InExpr - > GetType ( ) )
{
case FRigVMExprAST : : EType : : CallExtern :
{
2021-08-20 12:55:39 -04:00
Proxy = & InExpr - > To < FRigVMCallExternExprAST > ( ) - > GetProxy ( ) ;
2021-05-11 17:13:58 -04:00
break ;
}
case FRigVMExprAST : : EType : : NoOp :
{
2021-08-20 12:55:39 -04:00
Proxy = & InExpr - > To < FRigVMNoOpExprAST > ( ) - > GetProxy ( ) ;
2021-05-11 17:13:58 -04:00
break ;
}
case FRigVMExprAST : : EType : : Var :
{
2021-08-20 12:55:39 -04:00
Proxy = & InExpr - > To < FRigVMVarExprAST > ( ) - > GetProxy ( ) ;
2021-05-11 17:13:58 -04:00
break ;
}
case FRigVMExprAST : : EType : : Literal :
{
2021-08-20 12:55:39 -04:00
Proxy = & InExpr - > To < FRigVMLiteralExprAST > ( ) - > GetProxy ( ) ;
2021-05-11 17:13:58 -04:00
break ;
}
case FRigVMExprAST : : EType : : ExternalVar :
{
2021-08-20 12:55:39 -04:00
Proxy = & InExpr - > To < FRigVMExternalVarExprAST > ( ) - > GetProxy ( ) ;
2021-05-11 17:13:58 -04:00
break ;
}
case FRigVMExprAST : : EType : : Branch :
{
2021-08-20 12:55:39 -04:00
Proxy = & InExpr - > To < FRigVMBranchExprAST > ( ) - > GetProxy ( ) ;
2021-05-11 17:13:58 -04:00
break ;
}
case FRigVMExprAST : : EType : : If :
{
2021-08-20 12:55:39 -04:00
Proxy = & InExpr - > To < FRigVMIfExprAST > ( ) - > GetProxy ( ) ;
2021-05-11 17:13:58 -04:00
break ;
}
case FRigVMExprAST : : EType : : Select :
{
2021-08-20 12:55:39 -04:00
Proxy = & InExpr - > To < FRigVMSelectExprAST > ( ) - > GetProxy ( ) ;
2021-05-11 17:13:58 -04:00
break ;
}
2021-08-18 06:18:21 -04:00
case FRigVMExprAST : : EType : : Array :
{
2021-08-20 12:55:39 -04:00
Proxy = & InExpr - > To < FRigVMArrayExprAST > ( ) - > GetProxy ( ) ;
2021-08-18 06:18:21 -04:00
break ;
}
2021-05-11 17:13:58 -04:00
}
2021-08-20 12:55:39 -04:00
if ( Proxy ! = nullptr )
2021-05-11 17:13:58 -04:00
{
2021-08-20 12:55:39 -04:00
const FRigVMCallstack & Callstack = Proxy - > GetCallstack ( ) ;
ensure ( Callstack . Num ( ) > 0 ) ;
2021-08-26 10:32:00 -04:00
// Find all function references in the callstack and initialize their local variables if necessary
for ( int32 SubjectIndex = 0 ; SubjectIndex < Callstack . Num ( ) ; + + SubjectIndex )
2021-05-11 17:13:58 -04:00
{
2021-08-26 10:32:00 -04:00
if ( const URigVMLibraryNode * Node = Cast < const URigVMLibraryNode > ( Callstack [ SubjectIndex ] ) )
2021-05-11 17:13:58 -04:00
{
2021-08-26 10:32:00 -04:00
// Check if this is the first time we are accessing this function reference
bool bFound = false ;
for ( int32 i = ByteCode . GetNumInstructions ( ) - 1 ; i > 0 ; - - i )
2021-05-11 17:13:58 -04:00
{
2021-08-26 10:32:00 -04:00
const TArray < UObject * > * PreviousCallstack = ByteCode . GetCallstackForInstruction ( i ) ;
if ( PreviousCallstack & & PreviousCallstack - > Contains ( Node ) )
{
bFound = true ;
break ;
}
2021-05-11 17:13:58 -04:00
}
2021-08-26 10:32:00 -04:00
// If it is the first time we access this function reference, initialize all local variables
if ( ! bFound )
2021-05-11 17:13:58 -04:00
{
for ( FRigVMGraphVariableDescription Variable : Node - > GetContainedGraph ( ) - > LocalVariables )
{
2022-05-31 04:27:20 -04:00
const FRigVMCallstack LocalCallstack = Callstack . GetCallStackUpTo ( SubjectIndex ) ;
FString TargetPath = FString : : Printf ( TEXT ( " LocalVariable::%s|%s " ) , * LocalCallstack . GetCallPath ( ) , * Variable . Name . ToString ( ) ) ;
2021-06-07 06:49:07 -04:00
FString SourcePath = FString : : Printf ( TEXT ( " LocalVariableDefault::%s|%s::Const " ) , * Node - > GetContainedGraph ( ) - > GetGraphName ( ) , * Variable . Name . ToString ( ) ) ;
2021-05-17 12:35:41 -04:00
FRigVMOperand * TargetPtr = WorkData . PinPathToOperand - > Find ( TargetPath ) ;
FRigVMOperand * SourcePtr = WorkData . PinPathToOperand - > Find ( SourcePath ) ;
if ( SourcePtr & & TargetPtr )
2021-05-11 17:13:58 -04:00
{
2021-05-17 12:35:41 -04:00
const FRigVMOperand & Source = * SourcePtr ;
const FRigVMOperand & Target = * TargetPtr ;
2021-08-26 10:32:00 -04:00
2021-08-20 12:55:39 -04:00
ByteCode . AddCopyOp ( WorkData . VM - > GetCopyOpForOperands ( Source , Target ) ) ;
if ( Settings . SetupNodeInstructionIndex )
{
const int32 InstructionIndex = ByteCode . GetNumInstructions ( ) - 1 ;
WorkData . VM - > GetByteCode ( ) . SetSubject ( InstructionIndex , Callstack . GetCallPath ( ) , Callstack . GetStack ( ) ) ;
2021-08-26 10:32:00 -04:00
}
2021-08-20 12:55:39 -04:00
}
}
2021-05-11 17:13:58 -04:00
}
}
}
}
}
}
2022-04-05 06:57:59 -04:00
FString URigVMCompiler : : GetPinHashImpl ( const URigVMPin * InPin , const FRigVMVarExprAST * InVarExpr , bool bIsDebugValue , const FRigVMASTProxy & InPinProxy )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
FString Prefix = bIsDebugValue ? TEXT ( " DebugWatch: " ) : TEXT ( " " ) ;
2020-01-22 17:58:55 -05:00
FString Suffix ;
if ( InPin - > IsExecuteContext ( ) )
{
return TEXT ( " ExecuteContext! " ) ;
}
2020-09-24 00:43:27 -04:00
URigVMNode * Node = InPin - > GetNode ( ) ;
bool bIsExecutePin = false ;
bool bIsLiteral = false ;
bool bIsVariable = false ;
2020-01-22 17:58:55 -05:00
if ( InVarExpr ! = nullptr & & ! bIsDebugValue )
{
2021-08-18 06:18:21 -04:00
if ( InVarExpr - > IsA ( FRigVMExprAST : : ExternalVar ) )
2020-10-26 06:51:31 -04:00
{
2021-01-19 04:57:43 -04:00
URigVMPin : : FPinOverride PinOverride ( InVarExpr - > GetProxy ( ) , InVarExpr - > GetParser ( ) - > GetPinOverrides ( ) ) ;
FString VariablePath = InPin - > GetBoundVariablePath ( PinOverride ) ;
2020-10-26 06:51:31 -04:00
return FString : : Printf ( TEXT ( " %sVariable::%s%s " ) , * Prefix , * VariablePath , * Suffix ) ;
}
2021-08-18 06:18:21 -04:00
// for IO array pins we'll walk left and use that pin hash instead
if ( const FRigVMVarExprAST * SourceVarExpr = GetSourceVarExpr ( InVarExpr ) )
{
if ( SourceVarExpr ! = InVarExpr )
{
return GetPinHash ( SourceVarExpr - > GetPin ( ) , SourceVarExpr , bIsDebugValue ) ;
}
}
2020-09-24 00:43:27 -04:00
bIsExecutePin = InPin - > IsExecuteContext ( ) ;
bIsLiteral = InVarExpr - > GetType ( ) = = FRigVMExprAST : : EType : : Literal ;
2020-10-26 06:51:31 -04:00
bIsVariable = Cast < URigVMVariableNode > ( Node ) ! = nullptr | | InVarExpr - > IsA ( FRigVMExprAST : : ExternalVar ) ;
2020-01-22 17:58:55 -05:00
// determine if this is an initialization for an IO pin
2022-03-31 14:40:13 -04:00
if ( ! bIsLiteral & &
! bIsVariable & &
2020-09-24 00:43:27 -04:00
! bIsExecutePin & & ( InPin - > GetDirection ( ) = = ERigVMPinDirection : : IO | |
2020-01-22 17:58:55 -05:00
( InPin - > GetDirection ( ) = = ERigVMPinDirection : : Input & & InPin - > GetSourceLinks ( ) . Num ( ) = = 0 ) ) )
{
Suffix = TEXT ( " ::IO " ) ;
}
2020-12-03 12:09:21 -04:00
else if ( bIsLiteral )
{
Suffix = TEXT ( " ::Const " ) ;
}
2020-01-22 17:58:55 -05:00
}
2021-05-14 02:36:03 -04:00
bool bUseFullNodePath = true ;
2022-03-31 14:40:13 -04:00
if ( URigVMVariableNode * VariableNode = Cast < URigVMVariableNode > ( Node ) )
2020-01-22 17:58:55 -05:00
{
2021-05-11 17:13:58 -04:00
if ( InPin - > GetName ( ) = = TEXT ( " Value " ) & & ! bIsDebugValue )
2020-01-22 17:58:55 -05:00
{
2021-04-27 03:19:42 -04:00
FName VariableName = VariableNode - > GetVariableName ( ) ;
2021-06-02 06:17:52 -04:00
if ( VariableNode - > IsLocalVariable ( ) )
2021-05-11 17:13:58 -04:00
{
2021-06-02 06:17:52 -04:00
if ( bIsLiteral )
2021-05-11 17:13:58 -04:00
{
2021-06-02 06:17:52 -04:00
// Literal values will be reused for all instance of local variables
2022-03-31 14:40:13 -04:00
if ( InVarExpr & & InVarExpr - > NumParents ( ) = = 0 & & InVarExpr - > NumChildren ( ) = = 0 )
2021-06-07 06:49:07 -04:00
{
return FString : : Printf ( TEXT ( " %sLocalVariableDefault::%s|%s%s " ) , * Prefix , * Node - > GetGraph ( ) - > GetGraphName ( ) , * VariableName . ToString ( ) , * Suffix ) ;
}
2022-03-31 14:40:13 -04:00
else if ( InVarExpr )
{
const FString GraphPath = InVarExpr - > GetProxy ( ) . GetCallstack ( ) . GetCallPath ( false ) ;
return FString : : Printf ( TEXT ( " %sLocalVariable::%s|%s%s " ) , * Prefix , * GraphPath , * VariableName . ToString ( ) , * Suffix ) ;
}
2021-06-07 06:49:07 -04:00
else
{
return FString : : Printf ( TEXT ( " %sLocalVariable::%s|%s%s " ) , * Prefix , * Node - > GetGraph ( ) - > GetGraphName ( ) , * VariableName . ToString ( ) , * Suffix ) ;
}
2021-06-02 06:17:52 -04:00
}
else
{
if ( InVarExpr )
2021-04-27 03:19:42 -04:00
{
2021-06-02 06:17:52 -04:00
FRigVMASTProxy ParentProxy = InVarExpr - > GetProxy ( ) ;
while ( ParentProxy . GetCallstack ( ) . Num ( ) > 1 )
2021-04-27 03:19:42 -04:00
{
2021-06-02 06:17:52 -04:00
ParentProxy = ParentProxy . GetParent ( ) ;
if ( URigVMLibraryNode * LibraryNode = ParentProxy . GetSubject < URigVMLibraryNode > ( ) )
2021-05-11 17:13:58 -04:00
{
2022-05-31 04:27:20 -04:00
break ;
2021-05-11 17:13:58 -04:00
}
2021-04-27 03:19:42 -04:00
}
2021-06-02 06:17:52 -04:00
2022-05-31 04:27:20 -04:00
// Local variables for root / non-root graphs are in the format "LocalVariable::PathToGraph|VariableName"
const FString GraphPath = ParentProxy . GetCallstack ( ) . GetCallPath ( true ) ;
return FString : : Printf ( TEXT ( " %sLocalVariable::%s|%s%s " ) , * Prefix , * GraphPath , * VariableName . ToString ( ) , * Suffix ) ;
2021-04-27 03:19:42 -04:00
}
}
}
2022-03-31 14:40:13 -04:00
else if ( VariableNode - > IsInputArgument ( ) )
{
FString FullPath ;
if ( InPinProxy . IsValid ( ) )
{
FullPath = InPinProxy . GetCallstack ( ) . GetCallPath ( true ) ;
}
else if ( InVarExpr )
{
const FRigVMASTProxy NodeProxy = InVarExpr - > GetProxy ( ) . GetSibling ( Node ) ;
FullPath = InPinProxy . GetCallstack ( ) . GetCallPath ( true ) ;
}
return FString : : Printf ( TEXT ( " %s%s%s " ) , * Prefix , * FullPath , * Suffix ) ;
}
2021-05-11 17:13:58 -04:00
if ( ! bIsLiteral )
{
// determine if this variable needs to be remapped
if ( InVarExpr )
{
FRigVMASTProxy ParentProxy = InVarExpr - > GetProxy ( ) ;
while ( ParentProxy . GetCallstack ( ) . Num ( ) > 1 )
{
ParentProxy = ParentProxy . GetParent ( ) ;
if ( URigVMFunctionReferenceNode * FunctionReferenceNode = ParentProxy . GetSubject < URigVMFunctionReferenceNode > ( ) )
{
const FName RemappedVariableName = FunctionReferenceNode - > GetOuterVariableName ( VariableName ) ;
if ( ! RemappedVariableName . IsNone ( ) )
{
VariableName = RemappedVariableName ;
}
}
}
}
2021-04-27 03:19:42 -04:00
2021-05-11 17:13:58 -04:00
return FString : : Printf ( TEXT ( " %sVariable::%s%s " ) , * Prefix , * VariableName . ToString ( ) , * Suffix ) ;
}
}
2020-01-22 17:58:55 -05:00
}
2021-01-12 06:47:41 -04:00
else
{
2021-07-29 14:29:52 -04:00
if ( InVarExpr & & ! bIsDebugValue )
2021-01-12 06:47:41 -04:00
{
2021-05-14 02:36:03 -04:00
const FRigVMASTProxy NodeProxy = InVarExpr - > GetProxy ( ) . GetSibling ( Node ) ;
2021-01-12 06:47:41 -04:00
if ( const FRigVMExprAST * NodeExpr = InVarExpr - > GetParser ( ) - > GetExprForSubject ( NodeProxy ) )
{
// rely on the proxy callstack to differentiate registers
2021-05-14 02:36:03 -04:00
const FString CallStackPath = NodeProxy . GetCallstack ( ) . GetCallPath ( false /* include last */ ) ;
2021-01-12 06:47:41 -04:00
if ( ! CallStackPath . IsEmpty ( ) )
{
Prefix + = CallStackPath + TEXT ( " | " ) ;
2021-05-14 02:36:03 -04:00
bUseFullNodePath = false ;
2021-01-12 06:47:41 -04:00
}
}
2022-03-31 14:40:13 -04:00
else if ( Node - > IsA < URigVMFunctionEntryNode > ( ) | | Node - > IsA < URigVMFunctionReturnNode > ( ) )
{
const FString FullPath = InPinProxy . GetCallstack ( ) . GetCallPath ( true ) ;
return FString : : Printf ( TEXT ( " %s%s%s " ) , * Prefix , * FullPath , * Suffix ) ;
}
2021-01-12 06:47:41 -04:00
}
}
2022-03-31 14:40:13 -04:00
if ( InPinProxy . IsValid ( ) )
{
const FString FullPath = InPinProxy . GetCallstack ( ) . GetCallPath ( true ) ;
return FString : : Printf ( TEXT ( " %s%s%s " ) , * Prefix , * FullPath , * Suffix ) ;
}
if ( InVarExpr )
{
if ( bUseFullNodePath )
{
FString FullPath = InVarExpr - > GetProxy ( ) . GetCallstack ( ) . GetCallPath ( true ) ;
return FString : : Printf ( TEXT ( " %s%s%s " ) , * Prefix , * FullPath , * Suffix ) ;
}
else
{
return FString : : Printf ( TEXT ( " %s%s%s " ) , * Prefix , * InPin - > GetPinPath ( ) , * Suffix ) ;
}
}
FString PinPath = InPin - > GetPinPath ( bUseFullNodePath ) ;
return FString : : Printf ( TEXT ( " %s%s%s " ) , * Prefix , * PinPath , * Suffix ) ;
2020-01-22 17:58:55 -05:00
}
2022-04-05 06:57:59 -04:00
FString URigVMCompiler : : GetPinHash ( const URigVMPin * InPin , const FRigVMVarExprAST * InVarExpr , bool bIsDebugValue , const FRigVMASTProxy & InPinProxy )
{
const FString Hash = GetPinHashImpl ( InPin , InVarExpr , bIsDebugValue , InPinProxy ) ;
ensureMsgf ( ! Hash . Contains ( TEXT ( " FunctionLibrary:: " ) ) , TEXT ( " A library path should never be part of a pin hash %s. " ) , * Hash ) ;
return Hash ;
}
2021-08-18 06:18:21 -04:00
const FRigVMVarExprAST * URigVMCompiler : : GetSourceVarExpr ( const FRigVMExprAST * InExpr )
{
if ( InExpr )
{
if ( InExpr - > IsA ( FRigVMExprAST : : EType : : CachedValue ) )
{
return GetSourceVarExpr ( InExpr - > To < FRigVMCachedValueExprAST > ( ) - > GetVarExpr ( ) ) ;
}
if ( InExpr - > IsA ( FRigVMExprAST : : EType : : Var ) )
{
const FRigVMVarExprAST * VarExpr = InExpr - > To < FRigVMVarExprAST > ( ) ;
if ( VarExpr - > GetPin ( ) - > IsReferenceCountedContainer ( ) & &
( ( VarExpr - > GetPin ( ) - > GetDirection ( ) = = ERigVMPinDirection : : Input ) | | ( VarExpr - > GetPin ( ) - > GetDirection ( ) = = ERigVMPinDirection : : IO ) ) )
{
// if this is a variable setter we cannot follow the source var
if ( VarExpr - > GetPin ( ) - > GetDirection ( ) = = ERigVMPinDirection : : Input )
{
if ( VarExpr - > GetPin ( ) - > GetNode ( ) - > IsA < URigVMVariableNode > ( ) )
{
return VarExpr ;
}
}
if ( const FRigVMExprAST * AssignExpr = VarExpr - > GetFirstChildOfType ( FRigVMExprAST : : EType : : Assign ) )
{
// don't follow a copy assignment
if ( AssignExpr - > IsA ( FRigVMExprAST : : EType : : Copy ) )
{
return VarExpr ;
}
if ( const FRigVMExprAST * CachedValueExpr = VarExpr - > GetFirstChildOfType ( FRigVMExprAST : : EType : : CachedValue ) )
{
return GetSourceVarExpr ( CachedValueExpr - > To < FRigVMCachedValueExprAST > ( ) - > GetVarExpr ( ) ) ;
}
else if ( const FRigVMExprAST * ChildExpr = VarExpr - > GetFirstChildOfType ( FRigVMExprAST : : EType : : Var ) )
{
return GetSourceVarExpr ( ChildExpr - > To < FRigVMVarExprAST > ( ) ) ;
}
}
}
return VarExpr ;
}
}
return nullptr ;
}
2021-07-29 14:29:52 -04:00
void URigVMCompiler : : MarkDebugWatch ( bool bRequired , URigVMPin * InPin , URigVM * OutVM ,
TMap < FString , FRigVMOperand > * OutOperands , TSharedPtr < FRigVMParserAST > InRuntimeAST )
{
check ( InPin ) ;
check ( OutVM ) ;
check ( OutOperands ) ;
check ( InRuntimeAST . IsValid ( ) ) ;
URigVMPin * Pin = InPin - > GetRootPin ( ) ;
URigVMPin * SourcePin = Pin ;
if ( Settings . ASTSettings . bFoldAssignments )
{
while ( SourcePin - > GetSourceLinks ( ) . Num ( ) > 0 )
{
SourcePin = SourcePin - > GetSourceLinks ( ) [ 0 ] - > GetSourcePin ( ) ;
}
}
TArray < const FRigVMExprAST * > Expressions = InRuntimeAST - > GetExpressionsForSubject ( SourcePin ) ;
TArray < FRigVMOperand > VisitedKeys ;
for ( const FRigVMExprAST * Expression : Expressions )
{
check ( Expression - > IsA ( FRigVMExprAST : : EType : : Var ) ) ;
const FRigVMVarExprAST * VarExpression = Expression - > To < FRigVMVarExprAST > ( ) ;
if ( VarExpression - > GetPin ( ) = = Pin )
{
// literals don't need to be stored on the debug memory
if ( VarExpression - > IsA ( FRigVMExprAST : : Literal ) )
{
continue ;
}
}
const FString PinHash = GetPinHash ( SourcePin , VarExpression , false ) ;
if ( const FRigVMOperand * Operand = OutOperands - > Find ( PinHash ) )
{
const FRigVMASTProxy PinProxy = FRigVMASTProxy : : MakeFromUObject ( Pin ) ;
FRigVMVarExprAST TempVarExpr ( FRigVMExprAST : : EType : : Var , PinProxy ) ;
TempVarExpr . ParserPtr = InRuntimeAST . Get ( ) ;
const FString DebugPinHash = GetPinHash ( Pin , & TempVarExpr , true ) ;
const FRigVMOperand * DebugOperand = OutOperands - > Find ( DebugPinHash ) ;
if ( DebugOperand )
{
if ( DebugOperand - > IsValid ( ) )
{
FRigVMOperand KeyOperand ( Operand - > GetMemoryType ( ) , Operand - > GetRegisterIndex ( ) ) ; // no register offset
if ( bRequired )
{
if ( ! VisitedKeys . Contains ( KeyOperand ) )
{
OutVM - > OperandToDebugRegisters . FindOrAdd ( KeyOperand ) . AddUnique ( * DebugOperand ) ;
VisitedKeys . Add ( KeyOperand ) ;
}
}
else
{
TArray < FRigVMOperand > * MappedOperands = OutVM - > OperandToDebugRegisters . Find ( KeyOperand ) ;
if ( MappedOperands )
{
MappedOperands - > Remove ( * DebugOperand ) ;
if ( MappedOperands - > IsEmpty ( ) )
{
OutVM - > OperandToDebugRegisters . Remove ( KeyOperand ) ;
}
}
}
}
}
}
}
}
2020-01-22 17:58:55 -05:00
UScriptStruct * URigVMCompiler : : GetScriptStructForCPPType ( const FString & InCPPType )
{
if ( InCPPType = = TEXT ( " FRotator " ) )
{
return TBaseStructure < FRotator > : : Get ( ) ;
}
if ( InCPPType = = TEXT ( " FQuat " ) )
{
return TBaseStructure < FQuat > : : Get ( ) ;
}
if ( InCPPType = = TEXT ( " FTransform " ) )
{
return TBaseStructure < FTransform > : : Get ( ) ;
}
if ( InCPPType = = TEXT ( " FLinearColor " ) )
{
return TBaseStructure < FLinearColor > : : Get ( ) ;
}
if ( InCPPType = = TEXT ( " FColor " ) )
{
return TBaseStructure < FColor > : : Get ( ) ;
}
if ( InCPPType = = TEXT ( " FPlane " ) )
{
return TBaseStructure < FPlane > : : Get ( ) ;
}
if ( InCPPType = = TEXT ( " FVector " ) )
{
return TBaseStructure < FVector > : : Get ( ) ;
}
if ( InCPPType = = TEXT ( " FVector2D " ) )
{
return TBaseStructure < FVector2D > : : Get ( ) ;
}
if ( InCPPType = = TEXT ( " FVector4 " ) )
{
return TBaseStructure < FVector4 > : : Get ( ) ;
}
return nullptr ;
}
TArray < URigVMPin * > URigVMCompiler : : GetLinkedPins ( URigVMPin * InPin , bool bInputs , bool bOutputs , bool bRecursive )
{
TArray < URigVMPin * > LinkedPins ;
for ( URigVMLink * Link : InPin - > GetLinks ( ) )
{
if ( bInputs & & Link - > GetTargetPin ( ) = = InPin )
{
LinkedPins . Add ( Link - > GetSourcePin ( ) ) ;
}
else if ( bOutputs & & Link - > GetSourcePin ( ) = = InPin )
{
LinkedPins . Add ( Link - > GetTargetPin ( ) ) ;
}
}
if ( bRecursive )
{
for ( URigVMPin * SubPin : InPin - > GetSubPins ( ) )
{
LinkedPins . Append ( GetLinkedPins ( SubPin , bInputs , bOutputs , bRecursive ) ) ;
}
}
return LinkedPins ;
}
uint16 URigVMCompiler : : GetElementSizeFromCPPType ( const FString & InCPPType , UScriptStruct * InScriptStruct )
{
if ( InScriptStruct = = nullptr )
{
InScriptStruct = GetScriptStructForCPPType ( InCPPType ) ;
}
if ( InScriptStruct ! = nullptr )
{
return InScriptStruct - > GetStructureSize ( ) ;
}
if ( InCPPType = = TEXT ( " bool " ) )
{
return sizeof ( bool ) ;
}
else if ( InCPPType = = TEXT ( " int32 " ) )
{
return sizeof ( int32 ) ;
}
if ( InCPPType = = TEXT ( " float " ) )
{
return sizeof ( float ) ;
}
2021-06-22 14:11:52 -04:00
if ( InCPPType = = TEXT ( " double " ) )
{
return sizeof ( double ) ;
}
2020-01-22 17:58:55 -05:00
if ( InCPPType = = TEXT ( " FName " ) )
{
return sizeof ( FName ) ;
}
if ( InCPPType = = TEXT ( " FString " ) )
{
return sizeof ( FString ) ;
}
ensure ( false ) ;
return 0 ;
}
FRigVMOperand URigVMCompiler : : FindOrAddRegister ( const FRigVMVarExprAST * InVarExpr , FRigVMCompilerWorkData & WorkData , bool bIsDebugValue )
{
2021-08-18 06:18:21 -04:00
if ( ! bIsDebugValue )
{
InVarExpr = GetSourceVarExpr ( InVarExpr ) ;
}
2020-01-22 17:58:55 -05:00
if ( ! bIsDebugValue )
{
FRigVMOperand const * ExistingOperand = WorkData . ExprToOperand . Find ( InVarExpr ) ;
if ( ExistingOperand )
{
return * ExistingOperand ;
}
}
2021-01-19 04:57:43 -04:00
const URigVMPin : : FPinOverrideMap & PinOverrides = InVarExpr - > GetParser ( ) - > GetPinOverrides ( ) ;
URigVMPin : : FPinOverride PinOverride ( InVarExpr - > GetProxy ( ) , PinOverrides ) ;
2020-01-22 17:58:55 -05:00
URigVMPin * Pin = InVarExpr - > GetPin ( ) ;
2021-07-29 14:29:52 -04:00
if ( Pin - > IsExecuteContext ( ) & & bIsDebugValue )
{
return FRigVMOperand ( ) ;
}
2021-07-27 14:04:39 -04:00
FString CPPType = Pin - > GetCPPType ( ) ;
FString BaseCPPType = Pin - > IsArray ( ) ? Pin - > GetArrayElementCppType ( ) : CPPType ;
2020-01-22 17:58:55 -05:00
FString Hash = GetPinHash ( Pin , InVarExpr , bIsDebugValue ) ;
FRigVMOperand Operand ;
FString RegisterKey = Hash ;
bool bIsExecutePin = Pin - > IsExecuteContext ( ) ;
2020-11-18 07:48:31 -04:00
bool bIsLiteral = InVarExpr - > GetType ( ) = = FRigVMExprAST : : EType : : Literal & & ! bIsDebugValue ;
2021-04-29 09:47:07 -04:00
bool bIsVariable = Pin - > IsRootPin ( ) & & ( Pin - > GetName ( ) = = URigVMVariableNode : : ValueName ) & &
InVarExpr - > GetPin ( ) - > GetNode ( ) - > IsA < URigVMVariableNode > ( ) ;
2021-05-11 17:13:58 -04:00
// external variables don't require to add any register.
2021-04-29 09:47:07 -04:00
if ( bIsVariable & & ! bIsDebugValue )
{
for ( int32 ExternalVariableIndex = 0 ; ExternalVariableIndex < WorkData . VM - > GetExternalVariables ( ) . Num ( ) ; ExternalVariableIndex + + )
{
const FName & ExternalVariableName = WorkData . VM - > GetExternalVariables ( ) [ ExternalVariableIndex ] . Name ;
const FString ExternalVariableHash = FString : : Printf ( TEXT ( " Variable::%s " ) , * ExternalVariableName . ToString ( ) ) ;
if ( ExternalVariableHash = = Hash )
{
Operand = FRigVMOperand ( ERigVMMemoryType : : External , ExternalVariableIndex , INDEX_NONE ) ;
WorkData . ExprToOperand . Add ( InVarExpr , Operand ) ;
WorkData . PinPathToOperand - > FindOrAdd ( Hash ) = Operand ;
return Operand ;
}
}
}
2020-01-22 17:58:55 -05:00
2021-07-27 14:04:39 -04:00
const ERigVMMemoryType MemoryType =
bIsLiteral ? ERigVMMemoryType : : Literal :
( bIsDebugValue ? ERigVMMemoryType : : Debug : ERigVMMemoryType : : Work ) ;
2020-01-22 17:58:55 -05:00
FRigVMOperand const * ExistingOperand = WorkData . PinPathToOperand - > Find ( Hash ) ;
if ( ExistingOperand )
{
2021-07-27 14:04:39 -04:00
if ( ExistingOperand - > GetMemoryType ( ) = = MemoryType )
2020-01-22 17:58:55 -05:00
{
2021-04-29 05:02:50 -04:00
if ( ! bIsDebugValue )
{
check ( ! WorkData . ExprToOperand . Contains ( InVarExpr ) ) ;
WorkData . ExprToOperand . Add ( InVarExpr , * ExistingOperand ) ;
}
return * ExistingOperand ;
2020-01-22 17:58:55 -05:00
}
}
// create remaining operands / registers
if ( ! Operand . IsValid ( ) )
{
FName RegisterName = * RegisterKey ;
2021-07-27 14:04:39 -04:00
FString JoinedDefaultValue ;
2020-01-22 17:58:55 -05:00
TArray < FString > DefaultValues ;
if ( Pin - > IsArray ( ) )
{
if ( Pin - > GetDirection ( ) = = ERigVMPinDirection : : Hidden )
{
2021-07-27 14:04:39 -04:00
JoinedDefaultValue = Pin - > GetDefaultValue ( PinOverride ) ;
DefaultValues = URigVMPin : : SplitDefaultValue ( JoinedDefaultValue ) ;
2020-01-22 17:58:55 -05:00
}
else
{
2021-07-27 14:04:39 -04:00
JoinedDefaultValue = Pin - > GetDefaultValue ( PinOverride ) ;
if ( ! JoinedDefaultValue . IsEmpty ( ) )
{
if ( JoinedDefaultValue [ 0 ] = = TCHAR ( ' ( ' ) )
{
DefaultValues = URigVMPin : : SplitDefaultValue ( JoinedDefaultValue ) ;
}
else
{
DefaultValues . Add ( JoinedDefaultValue ) ;
}
}
2020-01-22 17:58:55 -05:00
}
while ( DefaultValues . Num ( ) < Pin - > GetSubPins ( ) . Num ( ) )
{
DefaultValues . Add ( FString ( ) ) ;
}
}
2020-09-24 00:43:27 -04:00
else if ( URigVMEnumNode * EnumNode = Cast < URigVMEnumNode > ( Pin - > GetNode ( ) ) )
{
2021-01-19 04:57:43 -04:00
FString EnumValueStr = EnumNode - > GetDefaultValue ( PinOverride ) ;
2020-09-24 00:43:27 -04:00
if ( UEnum * Enum = EnumNode - > GetEnum ( ) )
{
2021-07-27 14:04:39 -04:00
JoinedDefaultValue = FString : : FromInt ( ( int32 ) Enum - > GetValueByNameString ( EnumValueStr ) ) ;
DefaultValues . Add ( JoinedDefaultValue ) ;
2020-09-24 00:43:27 -04:00
}
else
{
2021-07-27 14:04:39 -04:00
JoinedDefaultValue = FString : : FromInt ( 0 ) ;
DefaultValues . Add ( JoinedDefaultValue ) ;
2020-09-24 00:43:27 -04:00
}
}
2020-01-22 17:58:55 -05:00
else
{
2021-07-27 14:04:39 -04:00
JoinedDefaultValue = Pin - > GetDefaultValue ( PinOverride ) ;
DefaultValues . Add ( JoinedDefaultValue ) ;
2020-01-22 17:58:55 -05:00
}
UScriptStruct * ScriptStruct = Pin - > GetScriptStruct ( ) ;
if ( ScriptStruct = = nullptr )
{
ScriptStruct = GetScriptStructForCPPType ( BaseCPPType ) ;
}
if ( ! Operand . IsValid ( ) )
{
2021-05-18 10:22:22 -04:00
const int32 NumSlices = 1 ;
2021-04-29 05:02:50 -04:00
int32 Register = INDEX_NONE ;
// debug watch register might already exists - look for them by name
2021-07-27 14:04:39 -04:00
if ( bIsDebugValue )
{
Operand = WorkData . FindProperty ( MemoryType , RegisterName ) ;
if ( Operand . IsValid ( ) )
{
2021-07-28 03:35:30 -04:00
FRigVMPropertyDescription Property = WorkData . GetProperty ( Operand ) ;
2021-07-27 14:04:39 -04:00
if ( Property . IsValid ( ) )
{
if ( ExistingOperand = = nullptr )
{
WorkData . PinPathToOperand - > Add ( Hash , Operand ) ;
}
return Operand ;
}
}
}
}
2021-07-29 14:29:52 -04:00
if ( bIsDebugValue )
{
// debug values are always stored as arrays
2022-03-31 14:40:13 -04:00
CPPType = RigVMTypeUtils : : ArrayTypeFromBaseType ( CPPType ) ;
2021-08-06 19:39:37 -04:00
JoinedDefaultValue = URigVMPin : : GetDefaultValueForArray ( { JoinedDefaultValue } ) ;
2021-07-29 14:29:52 -04:00
}
2021-07-30 15:49:56 -04:00
else if ( Pin - > GetDirection ( ) = = ERigVMPinDirection : : Hidden & & Pin - > GetNode ( ) - > IsA < URigVMUnitNode > ( ) )
{
UScriptStruct * UnitStruct = Cast < URigVMUnitNode > ( Pin - > GetNode ( ) ) - > GetScriptStruct ( ) ;
const FProperty * Property = UnitStruct - > FindPropertyByName ( Pin - > GetFName ( ) ) ;
check ( Property ) ;
if ( ! Property - > HasMetaData ( FRigVMStruct : : SingletonMetaName ) )
{
2022-03-31 14:40:13 -04:00
CPPType = RigVMTypeUtils : : ArrayTypeFromBaseType ( CPPType ) ;
2021-08-06 19:39:37 -04:00
JoinedDefaultValue = URigVMPin : : GetDefaultValueForArray ( { JoinedDefaultValue } ) ;
2021-07-30 15:49:56 -04:00
}
}
2021-08-07 15:31:27 -04:00
if ( Pin - > GetDirection ( ) = = ERigVMPinDirection : : Hidden )
{
JoinedDefaultValue . Empty ( ) ;
}
2021-08-18 06:18:21 -04:00
2021-07-27 14:04:39 -04:00
Operand = WorkData . AddProperty ( MemoryType , RegisterName , CPPType , Pin - > GetCPPTypeObject ( ) , JoinedDefaultValue ) ;
2020-01-22 17:58:55 -05:00
}
ensure ( Operand . IsValid ( ) ) ;
2021-03-19 12:43:05 -04:00
// Get all possible pins that lead to the same operand
2021-09-27 11:48:28 -04:00
if ( Settings . ASTSettings . bFoldAssignments )
2021-03-31 13:16:23 -04:00
{
2021-11-18 12:28:07 -05:00
// tbd: this functionality is only needed when there is a watch anywhere?
//if(!WorkData.WatchedPins.IsEmpty())
2021-03-31 13:16:23 -04:00
{
2021-11-18 12:28:07 -05:00
const FRigVMCompilerWorkData : : FRigVMASTProxyArray & PinProxies = FindProxiesWithSharedOperand ( InVarExpr , WorkData ) ;
ensure ( ! PinProxies . IsEmpty ( ) ) ;
for ( const FRigVMASTProxy & Proxy : PinProxies )
2021-09-27 11:48:28 -04:00
{
2021-11-18 12:28:07 -05:00
if ( URigVMPin * VirtualPin = Cast < URigVMPin > ( Proxy . GetSubject ( ) ) )
{
2022-03-31 14:40:13 -04:00
FString VirtualPinHash = GetPinHash ( VirtualPin , InVarExpr , bIsDebugValue , Proxy ) ;
2021-11-18 12:28:07 -05:00
WorkData . PinPathToOperand - > Add ( VirtualPinHash , Operand ) ;
}
}
2021-03-31 13:16:23 -04:00
}
}
else
2021-03-30 10:21:09 -04:00
{
2021-04-29 05:02:50 -04:00
if ( ExistingOperand = = nullptr )
{
WorkData . PinPathToOperand - > Add ( Hash , Operand ) ;
}
2021-03-19 12:43:05 -04:00
}
2021-04-01 09:40:45 -04:00
if ( ! bIsDebugValue )
{
check ( ! WorkData . ExprToOperand . Contains ( InVarExpr ) ) ;
WorkData . ExprToOperand . Add ( InVarExpr , Operand ) ;
}
2020-01-22 17:58:55 -05:00
return Operand ;
}
2021-11-18 12:28:07 -05:00
const FRigVMCompilerWorkData : : FRigVMASTProxyArray & URigVMCompiler : : FindProxiesWithSharedOperand ( const FRigVMVarExprAST * InVarExpr , FRigVMCompilerWorkData & WorkData )
2021-09-27 11:48:28 -04:00
{
2021-11-18 12:28:07 -05:00
const FRigVMASTProxy & InProxy = InVarExpr - > GetProxy ( ) ;
if ( const FRigVMCompilerWorkData : : FRigVMASTProxyArray * ExistingArray = WorkData . CachedProxiesWithSharedOperand . Find ( InProxy ) )
2021-09-27 11:48:28 -04:00
{
2021-11-18 12:28:07 -05:00
return * ExistingArray ;
}
FRigVMCompilerWorkData : : FRigVMASTProxyArray PinProxies , PinProxiesToProcess ;
const FRigVMCompilerWorkData : : FRigVMASTProxySourceMap & ProxySources = * WorkData . ProxySources ;
const FRigVMCompilerWorkData : : FRigVMASTProxyTargetsMap & ProxyTargets = WorkData . ProxyTargets ;
2021-09-27 11:48:28 -04:00
2021-11-18 12:28:07 -05:00
PinProxiesToProcess . Add ( InProxy ) ;
2022-03-31 14:40:13 -04:00
const FString CPPType = InProxy . GetSubjectChecked < URigVMPin > ( ) - > GetCPPType ( ) ;
2021-11-18 12:28:07 -05:00
for ( int32 ProxyIndex = 0 ; ProxyIndex < PinProxiesToProcess . Num ( ) ; ProxyIndex + + )
{
const FRigVMASTProxy & CurrentProxy = PinProxiesToProcess [ ProxyIndex ] ;
if ( CurrentProxy . IsValid ( ) )
2021-09-27 11:48:28 -04:00
{
2021-11-18 12:28:07 -05:00
if ( URigVMPin * Pin = Cast < URigVMPin > ( CurrentProxy . GetSubject ( ) ) )
2021-09-27 11:48:28 -04:00
{
2022-03-31 14:40:13 -04:00
if ( Pin - > GetNode ( ) - > IsA < URigVMVariableNode > ( ) )
2021-09-27 11:48:28 -04:00
{
if ( Pin - > GetDirection ( ) = = ERigVMPinDirection : : Input )
{
continue ;
}
}
2022-03-31 14:40:13 -04:00
// due to LWC we may have two pins that don't
// actually share the same CPP type (float vs double)
if ( Pin - > GetCPPType ( ) ! = CPPType )
{
continue ;
}
2021-09-27 11:48:28 -04:00
}
2021-11-18 12:28:07 -05:00
PinProxies . Add ( CurrentProxy ) ;
2021-09-27 11:48:28 -04:00
}
2021-11-18 12:28:07 -05:00
if ( const FRigVMASTProxy * SourceProxy = ProxySources . Find ( CurrentProxy ) )
2021-09-27 11:48:28 -04:00
{
2021-11-18 12:28:07 -05:00
if ( SourceProxy - > IsValid ( ) )
2021-09-27 11:48:28 -04:00
{
2021-11-18 12:28:07 -05:00
if ( ! PinProxies . Contains ( * SourceProxy ) & & ! PinProxiesToProcess . Contains ( * SourceProxy ) )
2021-09-27 11:48:28 -04:00
{
2021-11-18 12:28:07 -05:00
PinProxiesToProcess . Add ( * SourceProxy ) ;
}
}
}
if ( const FRigVMCompilerWorkData : : FRigVMASTProxyArray * TargetProxies = WorkData . ProxyTargets . Find ( CurrentProxy ) )
{
for ( const FRigVMASTProxy & TargetProxy : * TargetProxies )
{
if ( TargetProxy . IsValid ( ) )
{
if ( ! PinProxies . Contains ( TargetProxy ) & & ! PinProxiesToProcess . Contains ( TargetProxy ) )
2021-09-27 11:48:28 -04:00
{
2021-11-18 12:28:07 -05:00
PinProxiesToProcess . Add ( TargetProxy ) ;
2021-09-27 11:48:28 -04:00
}
}
}
}
}
2021-10-11 05:25:39 -04:00
if ( PinProxies . IsEmpty ( ) )
{
PinProxies . Add ( InVarExpr - > GetProxy ( ) ) ;
}
2021-11-18 12:28:07 -05:00
// store the cache for all other proxies within this group
for ( const FRigVMASTProxy & CurrentProxy : PinProxies )
{
if ( CurrentProxy ! = InProxy )
{
WorkData . CachedProxiesWithSharedOperand . Add ( CurrentProxy , PinProxies ) ;
}
}
// finally store and return the cache the the input proxy
return WorkData . CachedProxiesWithSharedOperand . Add ( InProxy , PinProxies ) ;
2021-09-27 11:48:28 -04:00
}
2021-09-08 07:57:30 -04:00
bool URigVMCompiler : : ValidateNode ( URigVMNode * InNode )
{
check ( InNode ) ;
2022-03-31 14:40:13 -04:00
if ( InNode - > HasWildCardPin ( ) )
2021-09-08 07:57:30 -04:00
{
2022-03-31 14:40:13 -04:00
static const FString UnknownTypeMessage = TEXT ( " Node @@ has unresolved pins of wildcard type. " ) ;
2021-09-08 07:57:30 -04:00
Settings . Report ( EMessageSeverity : : Error , InNode , UnknownTypeMessage ) ;
return false ;
}
return true ;
}
2020-01-22 17:58:55 -05:00
void URigVMCompiler : : ReportInfo ( const FString & InMessage )
{
2021-01-19 07:26:41 -04:00
if ( Settings . SurpressInfoMessages )
2020-01-22 17:58:55 -05:00
{
2021-01-19 07:26:41 -04:00
return ;
2020-01-22 17:58:55 -05:00
}
2021-01-19 07:26:41 -04:00
Settings . Report ( EMessageSeverity : : Info , nullptr , InMessage ) ;
2020-01-22 17:58:55 -05:00
}
void URigVMCompiler : : ReportWarning ( const FString & InMessage )
{
2021-01-19 07:26:41 -04:00
Settings . Report ( EMessageSeverity : : Warning , nullptr , InMessage ) ;
2020-01-22 17:58:55 -05:00
}
void URigVMCompiler : : ReportError ( const FString & InMessage )
{
2021-01-19 07:26:41 -04:00
Settings . Report ( EMessageSeverity : : Error , nullptr , InMessage ) ;
2020-01-22 17:58:55 -05:00
}