Last active
September 26, 2022 08:58
-
-
Save luc-tielen/909c97083b09ef8745b872bcca0de51d to your computer and use it in GitHub Desktop.
Compiling Eclair to WASM using walloc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This assumes eclair, clang and wasm-ld are installed, | |
# and that walloc (https://github.com/wingo/walloc) is compiled, | |
# and that walloc.o is copied to the current directory. | |
# Compiling (note: bulk memory needed for memset call) | |
eclair c program.eclair > program.ll | |
clang -DNDEBUG -Oz --target=wasm32 -mbulk-memory -nostdlib -c -o program.o program.ll | |
clang -DNDEBUG -Oz --target=wasm32 -mbulk-memory -nostdlib -c -o driver.o driver.c | |
# Linking | |
wasm-ld --no-entry --import-memory -o hello_world.wasm driver.o program.o walloc.o | |
# Running it | |
node run_eclair.js |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdbool.h> | |
#include <stdint.h> | |
typedef uint32_t size_t; | |
struct program; | |
extern struct program *eclair_program_init(); | |
extern void eclair_program_destroy(struct program *); | |
extern void eclair_program_run(struct program *); | |
extern void eclair_add_facts(struct program *, uint16_t fact_type, | |
uint32_t *data, size_t fact_count); | |
extern void eclair_add_fact(struct program *, uint16_t fact_type, | |
uint32_t *data); | |
extern uint32_t *eclair_get_facts(struct program *, uint16_t fact_type); | |
extern void eclair_free_buffer(uint32_t *data); | |
#define WASM_EXPORT(name) __attribute__((export_name(#name))) name | |
uint32_t WASM_EXPORT(run)(uint32_t result_index) { | |
struct program *prog = eclair_program_init(); | |
// edge(1,2), edge(2,3) | |
uint32_t data[] = {1, 2, 2, 3}; | |
eclair_add_facts(prog, 0, data, 2); | |
eclair_program_run(prog); | |
// NOTE: normally you call btree_size here to figure out the size, but I know | |
// there are only 3 facts | |
uint32_t *data_out = eclair_get_facts(prog, 1); | |
uint32_t result = data_out[result_index]; // dirty hack, since idk yet how to return arrays to JS | |
eclair_free_buffer(data_out); | |
eclair_program_destroy(prog); | |
return result; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@def edge(u32, u32). | |
@def path(u32, u32). | |
path(x, y) :- | |
edge(x, y). | |
path(x, z) :- | |
edge(x, y), | |
path(y, z). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require("fs"); | |
const bytes = fs.readFileSync("hello_world.wasm"); | |
const mod = new WebAssembly.Module(bytes); | |
const imports = { | |
env: { memory: new WebAssembly.Memory({ initial: 2, maximum: 256 }) }, | |
}; | |
const instance = new WebAssembly.Instance(mod, imports); | |
// This is a dirty hack, for now. This indexes into the results array of running Eclair. | |
// Not that familiar with WASM<->JS interface yet. | |
// Maybe we can directly use the full uint32 array? | |
for (const x of [0, 1, 2, 3, 4, 5]) { | |
console.log(instance.exports.run(x)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment