c3lang / c3c

Compiler for the C3 language
https://c3-lang.org
GNU Lesser General Public License v3.0
2.98k stars 184 forks source link

Introduce os::native_fputc() abstraction layer for File.write_byte() #1440

Closed rexim closed 2 months ago

rexim commented 2 months ago

Problem

Without it, using io::printn() in WASM is pretty much impossible, because it tries to call to libc::fputc specifically to just put \n at the end.

Steps to Reproduce

I'm using Node.js to simplify the setup. We will need 2 files:

// main.c3
import std::io;
import std::io::os;

extern fn void js_write(void *buffer, usz buffer_len);

fn void main() @extern("main") @wasm {
    os::native_fwrite_fn = fn usz!(void* f, char[] buffer) {
        js_write(&buffer[0], buffer.len);
        return buffer.len;
    };
    io::printn("Hello, World");
}
// main.js
const fs = require('fs');

let wasm = undefined;

function js_write(buffer, len) {
    console.log(new TextDecoder().decode(new Uint8ClampedArray(wasm.instance.exports.memory.buffer, buffer, len)));
}

(async () => {
    wasm = await WebAssembly.instantiate(fs.readFileSync('main.wasm'), {
        env: {js_write}
    });
    wasm.instance.exports._initialize();
    wasm.instance.exports.main();
})();

Steps to reproduce:

$ c3c --version
C3 Compiler Version:       0.6.3 (Pre-release, Sep 13 2024 16:59:02)
Installed directory:       /home/rexim/opt/c3-linux/bin/
Git Hash:                  6ff5ac5592b178350162d8bcb58cf00b8fd98f2a
Backends:                  LLVM
LLVM version:              18.1.8
LLVM default target:       x86_64-unknown-linux-gnu
$ node --version
v20.9.0
$ c3c compile -o main --target wasm32 --link-libc=no --no-entry -O5 -z --export-table -z --allow-undefined main.c3
] Assuming non-Posix environment
$ node main.js
Hello, World
wasm://wasm/main.wasm-0005b392:1

RuntimeError: unreachable
    at main.wasm.fputc (wasm://wasm/main.wasm-0005b392:wasm-function[4]:0x17c)
    at main.wasm.main (wasm://wasm/main.wasm-0005b392:wasm-function[2]:0x141)
    at /home/rexim/Programming/thirdparty/c3lang/c3c-issues/c3-wasm-io/main.js:15:27

Node.js v20.9.0
$
lerno commented 2 months ago

Thank you! And I think this is a future thing to improve, to add more hooks allowing people to sidestep libc with their own implementations.