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:
#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