Assembly Language for Beginners

(nextflipdebug2) #1

3.25. SETJMP/LONGJMP


...


/* return if bits() or decode() tries to read past available input */
if (setjmp(s.env) != 0) /* if came back here via longjmp(), */
err = 2; /* then skip decomp(), return error */
else
err = decomp(&s); /* decompress */

...


/* load at least need bits into val */
val = s->bitbuf;
while (s->bitcnt < need) {
if (s->left == 0) {
s->left = s->infun(s->inhow, &(s->in));
if (s->left == 0) longjmp(s->env, 1); /* out of input */

...


if (s->left == 0) {
s->left = s->infun(s->inhow, &(s->in));
if (s->left == 0) longjmp(s->env, 1); /* out of input */

( zlib/contrib/blast/blast.c )


Call tosetjmp()saves currentPC,SPand other registers intoenvstructure, then it returns 0.


In case of error,longjmp()teleportingyou into the point after right aftersetjmp()call, as ifsetjmp()
call returned non-null value (which was passed tolongjmp()). This reminds asfork()syscall in UNIX.


Now let’s take a look on distilled example:


#include <stdio.h>
#include <setjmp.h>


jmp_buf env;


void f2()
{
printf ("%s() begin\n", FUNCTION);
// something odd happened here
longjmp (env, 1234);
printf ("%s() end\n", FUNCTION);
};


void f1()
{
printf ("%s() begin\n", FUNCTION);
f2();
printf ("%s() end\n", FUNCTION);
};


int main()
{
int err=setjmp(env);
if (err==0)
{
f1();
}
else
{
printf ("Error %d\n", err);
};
};


If we run it, we will see:


f1() begin
f2() begin
Error 1234

Free download pdf