VFS support
We need it so that we can build TCC to make it run on WASM, or make it possible so that we can run TCC on Compiler Explorer.
I personally uses libtcc mainly for experimental headers and libraries embedding, so I can just compile libtcc.c and leverage the ONE_SOURCE feature. And then I instruct the C compiler to override the necessary functions.
if cfg!(feature = "vfs") {
cc.define("open", "vfs_open");
cc.define("read", "vfs_read");
cc.define("lseek", "vfs_lseek");
cc.define("close", "vfs_close");
}
And then I implemented a tiny VFS wrapper:
extern "C" {
fn open(path: *const c_char, oflag: c_int, ap: VaList) -> c_int;
}
#[no_mangle]
pub unsafe extern "C" fn vfs_open(path: *const c_char, oflag: c_int, mut args: ...) -> c_int {
fn insert_vfs(vfs: Box<impl VFS + Send + Sync + Clone + 'static>) -> c_int {
loop {
let vfs = vfs.clone();
let key: c_int = unsafe { RNG.gen_range(0..c_int::MAX) };
if let Ok(_) = unsafe { FILES.try_insert(key, vfs) } {
return key;
}
}
}
if let Ok(path) = CStr::from_ptr(path).to_str() {
let prefix = "memory:///headers/";
if path.starts_with(prefix) {
let path = path.strip_prefix(prefix).unwrap();
if let Some(file) = crate::headers::ASSET_MAP.get(path) {
return insert_vfs(Box::new(MemoryVFS::from_static(file.contents_bytes)));
}
}
let prefix = "memory:///libraries/";
if path.starts_with(prefix) {
let path = path.strip_prefix(prefix).unwrap();
if let Some(file) = crate::LIBRARIES.get_file(path) {
return insert_vfs(Box::new(MemoryVFS::from_static(file.contents())));
}
}
}
let fd = open(path, oflag, args.as_va_list());
if fd >= 0 {
insert_vfs(Box::new(PosixVFS::new(fd)))
} else {
fd
}
}
This one worked out pretty well, but I think this is very hacky, and there is a lack of write support. Specifically, if we want to run this on Godbolt, we need to capture the output executable, but the current implementation of TCC writes directly to a file descriptor. Instead, we should have a dynamic stream API that supports byte stream or file stream.
This is a mirror of tinycc.
@stevefan1999-personal Sounds good. Go for it dude. Fork the repo into another thing here on CChads (or your user) and you can start working
Sure thing
This is a mirror of tinycc.
I don't think this is exactly it because there are some changes not in mob branch. But I will try to push to both sides