It is definitely NOT safe to call most Accelstepper functions from an ISR.
The 'blocking' functions just calls the non-blocking function until the move is done:
// Blocks until the target position is reached and stopped
void AccelStepper::runToPosition()
{
while (run())
YIELD; // Let system housekeeping occur
}
I think the best way to handle limit switches is to write your own 'blocking' function instead of using the library function. Polling the limit switch between calls to .run(). On limit, call .stop() and then run to the new position. The 'stop' function sets the destination to the closest point where maximum deceleration can stop. You will need some compliance in your limit switch so the switch will activate before it is too late to stop.