please enjoy: my Wasm-hosted, Wasm-targeting build of Clang/Clang++/LLD: a self-contained, 25 MiB (gzipped) pure function
https://www.npmjs.com/package/@yowasp/clang
https://www.npmjs.com/package/@yowasp/clang
this C compiler is really fast! it can compile and link a simple C program in ~65 ms on my machine. (this involves spawning three Wasm "processes")
on the same machine, running the same command with a very similar Clang build natively takes ~80 ms.
this is fast enough for update-as-you-type live coding!
@snowfox @whitequark @s0 I don't think any of those support multiple pipelined transactions so it would be super slow.
Would be interesting to imagine what a pipelined variant would look like though
@s0 not bad, actually. Build once, optimise closer to the end user CPU
@whitequark this is great
import { runClang } from "npm:@yowasp/clang";
async function c(statics, ...rest) {
const { "a.out": wasm } = await runClang([
"clang",
"-nostartfiles",
"-Wl,--no-entry",
"-Wl,--export=malloc",
"-Wl,--export=free",
"input.c",
], {
"input.c": String.raw({ raw: statics }, ...rest) + "\n" +
'char* __Run(char* input) __attribute__((export_name("__Run"))) { return run(input); }\n',
});
const module = await WebAssembly.compile(wasm);
const enosys = () => {
return 52;
};
const instance = await WebAssembly.instantiate(module, {
wasi_snapshot_preview1: new Proxy({}, {
get(o, k) {
return enosys;
},
}),
});
return (...args) => {
const encoded = new TextEncoder().encode(JSON.stringify(args));
const inp = instance.exports.malloc(encoded.length);
new Uint8Array(instance.exports.memory.buffer, inp).set(encoded);
const ptr = instance.exports.__Run(inp);
instance.exports.free(inp);
if (ptr) {
const u8 = new Uint8Array(instance.exports.memory.buffer, ptr);
const str = new TextDecoder().decode(u8.subarray(0, u8.indexOf(0)));
instance.exports.free(ptr);
return JSON.parse(str);
}
return null;
};
}
const run = await c`
#include <string.h>
#include <stdio.h>
char* run(char* input){
char* out = 0;
input[strlen(input)-1] = 0;
asprintf(&out, "\\"hello, %s", input + 2);
return out;
}
`;
console.log(run("world"));