CorrM

ScriptCore

Jun 13th, 2019
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.65 KB | None | 0 0
  1. void UObject::ProcessEvent( UFunction* Function, void* Parms )
  2. {
  3.     checkf(!IsUnreachable(),TEXT("%s  Function: '%s'"), *GetFullName(), *Function->GetPathName());
  4.     checkf(!FUObjectThreadContext::Get().IsRoutingPostLoad, TEXT("Cannot call UnrealScript (%s - %s) while PostLoading objects"), *GetFullName(), *Function->GetFullName());
  5.  
  6. #if LIGHTWEIGHT_PROCESS_EVENT_COUNTER
  7.     CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_BlueprintTime, IsInGameThread() && ProcessEventCounter == 0);
  8.     TGuardValue<int32> PECounter(ProcessEventCounter, ProcessEventCounter+1);
  9. #endif
  10.  
  11. #if DO_BLUEPRINT_GUARD
  12.     FBlueprintExceptionTracker& BlueprintExceptionTracker = FBlueprintExceptionTracker::Get();
  13.     TGuardValue<int32> EntryCounter( BlueprintExceptionTracker.ScriptEntryTag, BlueprintExceptionTracker.ScriptEntryTag+1);
  14.  
  15.     CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_BlueprintTime, IsInGameThread() && BlueprintExceptionTracker.ScriptEntryTag == 1);
  16. #endif
  17.  
  18. #if TOTAL_OVERHEAD_SCRIPT_STATS
  19.     FBlueprintEventTimer::FScopedVMTimer VMTime;
  20. #endif // TOTAL_OVERHEAD_SCRIPT_STATS
  21.  
  22.     // Reject.
  23.     if (IsPendingKill())
  24.     {
  25.         return;
  26.     }
  27.    
  28. #if WITH_EDITORONLY_DATA
  29.     // Cannot invoke script events when the game thread is paused for debugging.
  30.     if(GIntraFrameDebuggingGameThread)
  31.     {
  32.         if(GFirstFrameIntraFrameDebugging)
  33.         {
  34.             UE_LOG(LogScriptCore, Warning, TEXT("Cannot call UnrealScript (%s - %s) while stopped at a breakpoint."), *GetFullName(), *Function->GetFullName());
  35.         }
  36.  
  37.         return;
  38.     }
  39. #endif  // WITH_EDITORONLY_DATA
  40.  
  41.     if ((Function->FunctionFlags & FUNC_Native) != 0)
  42.     {
  43.         int32 FunctionCallspace = GetFunctionCallspace(Function, Parms, NULL);
  44.         if (FunctionCallspace & FunctionCallspace::Remote)
  45.         {
  46.             CallRemoteFunction(Function, Parms, NULL, NULL);
  47.         }
  48.  
  49.         if ((FunctionCallspace & FunctionCallspace::Local) == 0)
  50.         {
  51.             return;
  52.         }
  53.     }
  54.     else if (Function->Script.Num() == 0)
  55.     {
  56.         return;
  57.     }
  58.     checkSlow((Function->ParmsSize == 0) || (Parms != NULL));
  59.  
  60. #if PER_FUNCTION_SCRIPT_STATS
  61.     const bool bShouldTrackFunction = Stats::IsThreadCollectingData();
  62.     FScopeCycleCounterUObject FunctionScope(bShouldTrackFunction ? Function : nullptr);
  63. #endif // PER_FUNCTION_SCRIPT_STATS
  64.  
  65. #if STATS || ENABLE_STATNAMEDEVENTS
  66.     const bool bShouldTrackObject = GVerboseScriptStats && Stats::IsThreadCollectingData();
  67.     FScopeCycleCounterUObject ContextScope(bShouldTrackObject ? this : nullptr);
  68. #endif
  69.  
  70. #if UE_BLUEPRINT_EVENTGRAPH_FASTCALLS
  71.     // Fast path for ubergraph calls
  72.     int32 EventGraphParams;
  73.     if (Function->EventGraphFunction != nullptr)
  74.     {
  75.         // Call directly into the event graph, skipping the stub thunk function
  76.         EventGraphParams = Function->EventGraphCallOffset;
  77.         Parms = &EventGraphParams;
  78.         Function = Function->EventGraphFunction;
  79.  
  80.         // Validate assumptions required for this optimized path (EventGraphFunction should have only been filled out if these held)
  81.         checkSlow(Function->ParmsSize == sizeof(EventGraphParams));
  82.         checkSlow(Function->FirstPropertyToInit == nullptr);
  83.         checkSlow(Function->PostConstructLink == nullptr);
  84.     }
  85. #endif
  86.  
  87.     // Scope required for scoped script stats.
  88.     {
  89.         uint8* Frame = NULL;
  90. #if USE_UBER_GRAPH_PERSISTENT_FRAME
  91.         if (Function->HasAnyFunctionFlags(FUNC_UbergraphFunction))
  92.         {
  93.             Frame = Function->GetOuterUClassUnchecked()->GetPersistentUberGraphFrame(this, Function);
  94.         }
  95. #endif
  96.         const bool bUsePersistentFrame = (NULL != Frame);
  97.         if (!bUsePersistentFrame)
  98.         {
  99.             Frame = (uint8*)FMemory_Alloca(Function->PropertiesSize);
  100.             // zero the local property memory
  101.             FMemory::Memzero(Frame + Function->ParmsSize, Function->PropertiesSize - Function->ParmsSize);
  102.         }
  103.  
  104.         // initialize the parameter properties
  105.         FMemory::Memcpy(Frame, Parms, Function->ParmsSize);
  106.  
  107.         // Create a new local execution stack.
  108.         FFrame NewStack(this, Function, Frame, NULL, Function->Children);
  109.  
  110.         checkSlow(NewStack.Locals || Function->ParmsSize == 0);
  111.  
  112.  
  113.  
  114.         // if the function has out parameters, fill the stack frame's out parameter info with the info for those params
  115.         if ( Function->HasAnyFunctionFlags(FUNC_HasOutParms) )
  116.         {
  117.             FOutParmRec** LastOut = &NewStack.OutParms;
  118.             for ( UProperty* Property = (UProperty*)Function->Children; Property && (Property->PropertyFlags&(CPF_Parm)) == CPF_Parm; Property = (UProperty*)Property->Next )
  119.             {
  120.                 // this is used for optional parameters - the destination address for out parameter values is the address of the calling function
  121.                 // so we'll need to know which address to use if we need to evaluate the default parm value expression located in the new function's
  122.                 // bytecode
  123.                 if ( Property->HasAnyPropertyFlags(CPF_OutParm) )
  124.                 {
  125.                     CA_SUPPRESS(6263)
  126.                     FOutParmRec* Out = (FOutParmRec*)FMemory_Alloca(sizeof(FOutParmRec));
  127.                     // set the address and property in the out param info
  128.                     // note that since C++ doesn't support "optional out" we can ignore that here
  129.                     Out->PropAddr = Property->ContainerPtrToValuePtr<uint8>(Parms);
  130.                     Out->Property = Property;
  131.  
  132.                     // add the new out param info to the stack frame's linked list
  133.                     if (*LastOut)
  134.                     {
  135.                         (*LastOut)->NextOutParm = Out;
  136.                         LastOut = &(*LastOut)->NextOutParm;
  137.                     }
  138.                     else
  139.                     {
  140.                         *LastOut = Out;
  141.                     }
  142.                 }
  143.             }
  144.  
  145.             // set the next pointer of the last item to NULL to mark the end of the list
  146.             if (*LastOut)
  147.             {
  148.                 (*LastOut)->NextOutParm = NULL;
  149.             }
  150.         }
  151.  
  152.         if (!bUsePersistentFrame)
  153.         {
  154.             for (UProperty* LocalProp = Function->FirstPropertyToInit; LocalProp != NULL; LocalProp = (UProperty*)LocalProp->Next)
  155.             {
  156.                 LocalProp->InitializeValue_InContainer(NewStack.Locals);
  157.             }
  158.         }
  159.  
  160.         // Call native function or UObject::ProcessInternal.
  161.         const bool bHasReturnParam = Function->ReturnValueOffset != MAX_uint16;
  162.         uint8* ReturnValueAddress = bHasReturnParam ? ((uint8*)Parms + Function->ReturnValueOffset) : nullptr;
  163.         Function->Invoke(this, NewStack, ReturnValueAddress);
  164.  
  165.         if (!bUsePersistentFrame)
  166.         {
  167.             // Destroy local variables except function parameters.!! see also UObject::CallFunctionByNameWithArguments
  168.             // also copy back constructed value parms here so the correct copy is destroyed when the event function returns
  169.             for (UProperty* P = Function->DestructorLink; P; P = P->DestructorLinkNext)
  170.             {
  171.                 if (!P->IsInContainer(Function->ParmsSize))
  172.                 {
  173.                     P->DestroyValue_InContainer(NewStack.Locals);
  174.                 }
  175.                 else if (!(P->PropertyFlags & CPF_OutParm))
  176.                 {
  177.                     FMemory::Memcpy(P->ContainerPtrToValuePtr<uint8>(Parms), P->ContainerPtrToValuePtr<uint8>(NewStack.Locals), P->ArrayDim * P->ElementSize);
  178.                 }
  179.             }
  180.         }
  181.     }
  182.  
  183. #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
  184. #if WITH_EDITORONLY_DATA
  185.     FBlueprintCoreDelegates::OnScriptExecutionEnd.Broadcast();
  186. #endif
  187. #endif
  188. }
Add Comment
Please, Sign In to add comment