Documentation
Language Guide
C
Tutorials
Longjmp

longjmp and setjmp in WASIX

This sample project demonstrates how longjmp and setjmp works in WASIX.

Prerequisites

⚠️

Please check that you have the latest version of wasmer runtime as this tutorial depends on version 4.1.1 or higher.

The project requires the following tools to be installed on your system:

Start a new project

Create a new directory for your project:

$ mkdir wasix-jump
$ cd wasix-jump

Make a new file called jump.c:

$ touch jump.c

Link the SysRoot

ℹ️

You need to link the SysRoot to your project. The SysRoot is a directory that contains the WASI libc headers and libraries. The SysRoot is located in the Wasix-libc binary or you can compile it yourself.

Writing the Application

Basic Application Setup

We want to write a simple C program that demonstrates how to use the opendir and jump functions to read the contents of a directory. It takes a single command-line argument, which is the path to the directory to read.

Let's write code for the above:

jump.c
#include <stdio.h>
#include <setjmp.h>
 
jmp_buf bufferA, bufferB;
 
__attribute__((noinline)) void routineB(); // forward declaration
 
__attribute__((noinline)) void routineA()
{
    int r = 1;
 
    printf("(A1)\n");
 
    r = setjmp(bufferA); // save the current context in bufferA
    if (r == 0)
        routineB(); // call routineB() and pass control to it
 
    printf("(A2) r=%d\n", r); // r will be 10001
 
    r = setjmp(bufferA);
    if (r == 0)
        longjmp(bufferB, 20001); // pass control to bufferB and return 20001
 
    printf("(A3) r=%d\n", r); // r will be 10002
 
    r = setjmp(bufferA);
    if (r == 0)
        longjmp(bufferB, 20002); // pass control to bufferB and return 20002
 
    printf("(A4) r=%d\n", r); // r will be 10003
}
 
__attribute__((noinline)) void routineB()
{
    int r;
 
    printf("(B1)\n");
 
    r = setjmp(bufferB); // save the current context in bufferB
    if (r == 0)
        longjmp(bufferA, 10001); // pass control to bufferA and return 10001
 
    printf("(B2) r=%d\n", r); // r will be 20001
 
    r = setjmp(bufferB);
    if (r == 0)
        longjmp(bufferA, 10002); // pass control to bufferA and return 10002
 
    printf("(B3) r=%d\n", r); // r will be 20002
 
    r = setjmp(bufferB);
    if (r == 0)
        longjmp(bufferA, 10003); // pass control to bufferA and return 10003
}
 
int main(int argc, char **argv)
{
    routineA(); // call routineA() and pass control to it
    return 0;
}

Compiling the Application

Let's compile the application with WASIX:

$ /path/to/wasix-sdk/clang jump.c --target="wasm32-wasi" -o jump.wasm

It's compiling! Now, let's try to run it:

$ wasmer run jump.wasm /
(A1)
(B1)
(A2) r=10001
(B2) r=20001
(A3) r=10002
(B3) r=20002
(A4) r=10003

Yaay, It works!

Conclusion

In this tutorial we learned:

  • How to use longjmp and setjmp in C
  • Compiling a C program with WASIX
wasix-libc/examples/longjmp.c