I get the idea behind thunks, but I’m struggling at understanding some details.
What exactly is the Stack? I mean I know what a stack is, but not how it’s being used in this context.
Sometimes it seems to be explained as the function execution stack, or maybe something with memory pointers to the parameters passed into the function, but it’s still very unclear to me.
Every function call in BPVM (whether native function or script function/event) handled the same way:
BPVM reads the related UFunction* that get linked in runtime we mentioned earlier, and reads its properties, like what kind of params it has and total size of its parameters.
A memory block is allocated before function call happens (via FMemory__Alloca__Aligned macro). Size of this memory block is equal to total size of the paramters of your function. This is what we call “parms memory”.
When a function call happens, all the existing parameters in stack/graph that created for the function parameter is copied to said memory block. For example, if you have a local float variable in a BP function, and if thats plugged to a pin of a node that is a custom thunk, that float variable is copied to “parms memory” block BPVM allocated just before this step.
This “parms memory” can be accessed through FFrame::Locals, because FFrame::Locals is a uint8* pointer that points to the allocated “parms memory”. When you use PARAM_PASSED_BY_VAL macros or use Stack.StepCompiledIn<FProperty>(Object, &Thing) you actually walk through Locals. This part is a bit confusing and it’s normal if you’re lost, but bear with me.