Create a new directory in your /book-examples directory named /compile-with-llvm. Create a new file in the /compile-with-llvm directory named main.cpp and populate it with the following contents:
#include <stdbool.h>
#define BOUNDS 255
#define RECT_SIDE 50
#define BOUNCE_POINT (BOUNDS - RECT_SIDE)
bool isRunning = true;
typedef struct Rect {
int x;
int y;
char direction;
} Rect;
struct Rect rect;
void updateRectLocation() {
if (rect.x == BOUNCE_POINT) rect.direction = 'L';
if (rect.x == 0) rect.direction = 'R';
int incrementer = 1;
if (rect.direction == 'L') incrementer = -1;
rect.x = rect.x + incrementer;
rect.y = rect.y + incrementer;
}
extern "C" {
extern int jsClearRect();
extern int jsFillRect(int x, int y, int width, int height);
__attribute__((visibility("default")))
void moveRect() {
jsClearRect();
updateRectLocation();
jsFillRect(rect.x, rect.y, RECT_SIDE, RECT_SIDE);
}
__attribute__((visibility("default")))
bool getIsRunning() {
return isRunning;
}
__attribute__((visibility("default")))
void setIsRunning(bool newIsRunning) {
isRunning = newIsRunning;
}
__attribute__((visibility("default")))
void init() {
rect.x = 0;
rect.y = 0;
rect.direction = 'R';
setIsRunning(true);
}
}
The code in this file is almost identical to the contents of without-glue.c from Chapter 5, Creating and Loading a WebAssembly Module. The comments have been removed from the file and the imported/exported functions are wrapped in an extern "C" block. The __attribute__((visibility("default"))) lines are macro statements (similar to EMSCRIPTEN_KEEPALIVE) that ensure the functions aren't removed from the compiled output during the dead-code elimination step. Just as with prior examples, we'll interact with the compiled Wasm module through an HTML file. Let's create that next.