If the handwritten code calls no other code, then this is fine, the scheduler knows it can replace the succip variable and when a proceed() occurs, execution will return to mercury code which it knows about.
If handwritten code calls other handwritten code, we have a problem, as succip will be saved on the stack and we don't know where on the stack it is stored. So we use a global variable 'saved_succip' which is succip is saved into. Care must be taken to save saved_succip on the stack so it doesn't get clobbered. So
detstackvar(1) = (int) succip;becomes
detstackvar(1) = (int) saved_succip; saved_succip = (int) succip;and, when restoring,
succip = (int) detstackvar(1);becomes
succip = saved_succip; saved_succip = detstackvar(1);
(With appropriate LVALUE_CASTs).
In this way, garbage collection always knows where the succip is stored in handwritten code.
The garbage collection code must check that the current execution is not still in a handwritten predicate -- if it is, it must re-schedule (essentially just the same as before).