Don't confuse execution order with simulation time. Seqential statements execute in sequential order, one after the other, without consuming any simulation time (except a wait statement). Simulation time only advances while the process is suspended (e.g. waiting for the next clock edge, whether explicitly executing a wait statement, or implicitly at the bottom of a process that has a sensitvity list).
If w_ptr_reg is a signal, its value is not actually updated until (in execution order) the process suspends (to wait for another clock). So, references to a signal, whether they occur before or after (in execution order, not simulation time) the assignment to it, return the non-updated value. This is different from how software code works in typical programming languages.
If w_ptr_reg is a variable, it works just like software; the variable is updated immediately upon execution of the assignment statement (or procedure call, if it is an out or inout parameter). So references to a variable occurring before (in execution order) the assignment will return the non-updated value, but references to the variable occuring after (in execution order) the assignment will return the updated value.
Whether you use variables or signals, the synthesis tool will create hardware (i.e. gates and registers) that mimics the simulation behavior of the code. Whether that hardware is fits in the device or meets timing constraints is a different issue. I find it works best for me if I focus on coding the correct behavior, then worry about what hardware it generates if it does not fit or meet timing. Of course, with experience comes the knowledge of what types of behavior take too much resources or won't meet timing! Because of my preference and experience, I use more variables, saving signals for only inter- process communications.