longjmp
and setjmp
in WASIX
This sample project demonstrates how longjmp and setjmp works in WASIX.
Prerequisites
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
andsetjmp
in C - Compiling a C program with WASIX